Files
cleveragents-core/features/steps/module_coverage_steps.py
T
brent.edwards f4432c2759
CI / quality (push) Has been cancelled
CI / integration_tests (push) Has been cancelled
CI / e2e_tests (push) Has been cancelled
CI / build (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / security (push) Has been cancelled
CI / benchmark-publish (push) Has been cancelled
CI / unit_tests (push) Has been cancelled
CI / helm (push) Has been cancelled
CI / coverage (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / status-check (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
refactor(cleanup): remove or implement empty stub packages
Remove four empty stub packages that contained only __init__.py with
__all__ = [] and no functional code, violating CONTRIBUTING.md §Commit
Completeness. All four were audited against docs/specification.md:

- src/cleveragents/runtime/ — Spec defines four layers (Domain,
  Application, Infrastructure, Presentation) with no Runtime Layer.
  Runtime concepts (LSP Runtime, actor runtime) belong in Infrastructure.
- src/cleveragents/domain/repositories/ — Spec mentions repository
  interfaces in Domain but mandates no separate subpackage. Empty with
  no protocols defined; existing models cover the domain.
- src/cleveragents/domain/plans/ — Plan domain models already exist in
  domain/models/planconfig, planfiles, and plansettings. Empty duplicate.
- src/cleveragents/application/workflows/ — Application logic already
  served by application/services/. Empty stub added no value.

Updated test references in features/steps/module_coverage_steps.py,
features/steps/coverage_extras_steps.py, features/architecture.feature,
and robot/architecture.robot to remove the deleted packages from import
verification and architecture validation lists.

ISSUES CLOSED: #948

Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-04-02 16:58:36 +00:00

271 lines
8.7 KiB
Python

"""Step definitions for module entry points coverage tests."""
import os
from unittest.mock import patch
from behave import given, then, when
from cleveragents.application.container import Container
from cleveragents.cli.main import app as main_app
from cleveragents.config.settings import Settings
from cleveragents.core.exceptions import CleverAgentsError, RateLimitError
from cleveragents.platform import ensure_cli_importable
@when("I execute the __main__ module directly")
def step_execute_main_module(context):
"""Execute __main__ module via in-process CliRunner (avoids subprocess)."""
from typer.testing import CliRunner
try:
runner = CliRunner()
result = runner.invoke(main_app, ["--version"])
# Wrap in a namespace so downstream steps see .returncode/.stdout/.stderr
context.result = type(
"R",
(),
{
"returncode": result.exit_code,
"stdout": result.stdout or "",
"stderr": "",
},
)()
context.execution_success = result.exit_code == 0
except Exception as e:
context.execution_success = False
context.error = e
@when("I execute the __main__ module with arguments")
def step_execute_main_with_args(context):
"""Execute __main__ module with arguments via in-process CliRunner."""
from typer.testing import CliRunner
try:
runner = CliRunner()
result = runner.invoke(main_app, ["info"])
context.result = type(
"R",
(),
{
"returncode": result.exit_code,
"stdout": result.stdout or "",
"stderr": "",
},
)()
context.args_processed = result.exit_code == 0
except Exception as e:
context.args_processed = False
context.error = e
@when("I execute the __main__ module and interrupt it")
def step_execute_main_with_interrupt(context):
"""Execute __main__ module and simulate interrupt."""
with patch("cleveragents.__main__.main") as mock_main:
mock_main.side_effect = KeyboardInterrupt()
try:
context.interrupt_handled = False
except KeyboardInterrupt:
context.interrupt_handled = True
@when("I import all application modules directly")
def step_import_all_modules(context):
"""Import all application modules."""
modules_to_import = [
"cleveragents",
"cleveragents.application",
"cleveragents.application.services",
"cleveragents.cli",
"cleveragents.cli.commands",
"cleveragents.config",
"cleveragents.core",
"cleveragents.domain",
"cleveragents.domain.contexts",
"cleveragents.domain.models",
"cleveragents.infrastructure",
"cleveragents.providers",
"cleveragents.shared",
]
context.import_errors = []
for module_name in modules_to_import:
try:
__import__(module_name)
except ImportError as e:
context.import_errors.append((module_name, str(e)))
@when("I test all exception classes")
def step_test_exception_classes(context):
"""Test all exception classes."""
context.exceptions_tested = []
# Test CleverAgentsError
error1 = CleverAgentsError("Test error")
assert str(error1) == "Test error"
context.exceptions_tested.append("CleverAgentsError")
# Test CleverAgentsError with details
error2 = CleverAgentsError("Test error", details={"key": "value"})
assert str(error2) == "Test error"
assert error2.details == {"key": "value"}
context.exceptions_tested.append("CleverAgentsError with details")
# Test RateLimitError
error3 = RateLimitError("Rate limit hit")
assert str(error3) == "Rate limit hit"
context.exceptions_tested.append("RateLimitError")
@given("environment variables are set")
def step_set_environment_variables(context):
"""Set environment variables."""
os.environ["CLEVERAGENTS_PROJECT_ROOT"] = "/test/project"
os.environ["CLEVERAGENTS_LOG_LEVEL"] = "DEBUG"
os.environ["OPENAI_API_KEY"] = "test_openai_key"
context.env_set = True
@given("no API keys are configured")
def step_no_api_keys(context):
"""Remove API keys from environment."""
for key in ["OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GOOGLE_API_KEY"]:
os.environ.pop(key, None)
context.no_keys = True
@when("I create a container")
def step_create_container(context):
"""Create an application container."""
try:
context.container = Container()
context.container_created = True
except Exception as e:
context.container_created = False
context.container_error = e
@when("I create settings with invalid values")
def step_create_invalid_settings(context):
"""Create settings with invalid values."""
try:
# Settings should handle invalid values gracefully
with patch.dict(os.environ, {"CLEVERAGENTS_LOG_LEVEL": "INVALID"}):
settings = Settings()
context.settings_created = True
context.settings = settings
except Exception as e:
context.settings_created = False
context.settings_error = e
@when("I test platform module functions")
def step_test_platform_functions(context):
"""Test platform module functions."""
try:
# Test ensure_cli_importable
ensure_cli_importable()
context.platform_tested = True
except Exception as e:
context.platform_tested = False
context.platform_error = e
@when("I use CLI shortcut commands")
def step_test_cli_shortcuts(context):
"""Test CLI shortcut commands."""
from typer.testing import CliRunner
runner = CliRunner()
context.shortcuts_tested = []
# Test version shortcut
result = runner.invoke(main_app, ["version"])
context.shortcuts_tested.append(("version", result.exit_code))
# Test info shortcut
result = runner.invoke(main_app, ["info"])
context.shortcuts_tested.append(("info", result.exit_code))
# Test diagnostics shortcut
result = runner.invoke(main_app, ["diagnostics"])
context.shortcuts_tested.append(("diagnostics", result.exit_code))
@then("the module should run successfully")
def step_verify_module_execution(context):
"""Verify module executed successfully."""
assert context.execution_success
@then("the module should process arguments correctly")
def step_verify_args_processed(context):
"""Verify arguments were processed."""
assert context.args_processed
@then("the module should handle keyboard interrupt")
def step_verify_interrupt_handled(context):
"""Verify keyboard interrupt was handled."""
# The interrupt is expected behavior
assert context.interrupt_handled or not context.interrupt_handled
@then("all modules should import without error")
def step_verify_module_imports(context):
"""Verify all modules imported successfully."""
assert len(context.import_errors) == 0, f"Import errors: {context.import_errors}"
@then("all exceptions should work correctly")
def step_verify_exceptions(context):
"""Verify all exceptions work correctly."""
assert len(context.exceptions_tested) >= 3
assert "CleverAgentsError" in context.exceptions_tested
assert "CleverAgentsError with details" in context.exceptions_tested
assert "RateLimitError" in context.exceptions_tested
@then("the container should use environment settings")
def step_verify_container_with_env(context):
"""Verify container uses environment settings."""
assert context.container_created
# Clean up environment
os.environ.pop("CLEVERAGENTS_PROJECT_ROOT", None)
os.environ.pop("CLEVERAGENTS_LOG_LEVEL", None)
os.environ.pop("OPENAI_API_KEY", None)
@then("the container should handle missing keys")
def step_verify_container_without_keys(context):
"""Verify container handles missing keys."""
# Container should still be created even without API keys
assert context.container_created or not context.container_created
@then("validation should handle errors properly")
def step_verify_settings_validation(context):
"""Verify settings validation."""
assert context.settings_created # Settings should still be created with defaults
@then("all platform functions should work")
def step_verify_platform_functions(context):
"""Verify platform functions work."""
assert context.platform_tested
@then("shortcuts should map to full commands")
def step_verify_shortcuts(context):
"""Verify CLI shortcuts work."""
assert len(context.shortcuts_tested) >= 3
# Shortcuts should execute (exit code 0) or fail gracefully
for cmd, exit_code in context.shortcuts_tested:
assert exit_code in [0, 1, 2], (
f"Command {cmd} had unexpected exit code {exit_code}"
)