forked from HAL9000/cleveragents-core
358 lines
9.7 KiB
Python
358 lines
9.7 KiB
Python
import asyncio
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
from unittest.mock import patch
|
|
|
|
import yaml
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
from cleveragents.core.application import CleverAgentsApp
|
|
from cleveragents.core.exceptions import CleverAgentsException
|
|
|
|
|
|
@given("I create a CleverAgentsApp without configuration")
|
|
def step_impl(context):
|
|
context.app = CleverAgentsApp()
|
|
|
|
|
|
@then("the application should be initialized with default values")
|
|
def step_impl(context):
|
|
assert context.app.config_manager is not None
|
|
assert context.app.agent_factory is None
|
|
assert context.app.graph_builder is None
|
|
|
|
|
|
@when("I load configuration from test files")
|
|
def step_impl(context):
|
|
# Create a temporary configuration file
|
|
context.temp_dir = tempfile.TemporaryDirectory()
|
|
config_path = Path(context.temp_dir.name) / "test_config.yaml"
|
|
|
|
# Create a minimal valid configuration
|
|
config = {
|
|
"agents": {
|
|
"test_agent": {
|
|
"type": "llm",
|
|
"config": {
|
|
"provider": "openai",
|
|
"model": "test-model",
|
|
"api_key": "mock-api-key",
|
|
},
|
|
}
|
|
},
|
|
"routing": {
|
|
"name": "main_router",
|
|
"flows": [
|
|
{"from": "input", "to": "test_agent"},
|
|
{"from": "test_agent", "to": "output"},
|
|
],
|
|
},
|
|
}
|
|
|
|
with open(config_path, "w") as f:
|
|
yaml.dump(config, f)
|
|
|
|
context.config_files = [config_path]
|
|
context.app.load_configuration(context.config_files)
|
|
|
|
|
|
@then("the configuration should be loaded successfully")
|
|
def step_impl(context):
|
|
assert context.app.agent_factory is not None
|
|
assert context.app.graph_builder is not None
|
|
|
|
|
|
@given("I create a CleverAgentsApp with test configuration")
|
|
def step_impl(context):
|
|
# Create a temporary configuration file
|
|
context.temp_dir = tempfile.TemporaryDirectory()
|
|
config_path = Path(context.temp_dir.name) / "test_config.yaml"
|
|
|
|
# Create a minimal valid configuration
|
|
config = {
|
|
"agents": {
|
|
"test_agent": {
|
|
"type": "llm",
|
|
"config": {
|
|
"provider": "openai",
|
|
"model": "test-model",
|
|
"api_key": "mock-api-key",
|
|
},
|
|
}
|
|
},
|
|
"routing": {
|
|
"name": "main_router",
|
|
"flows": [
|
|
{"from": "input", "to": "test_agent"},
|
|
{"from": "test_agent", "to": "output"},
|
|
],
|
|
},
|
|
}
|
|
|
|
with open(config_path, "w") as f:
|
|
yaml.dump(config, f)
|
|
|
|
context.config_files = [config_path]
|
|
context.app = CleverAgentsApp(context.config_files)
|
|
|
|
|
|
@when('I run the application in single-shot mode with prompt "{prompt}"')
|
|
def step_impl(context, prompt):
|
|
# Mock the run_single_shot method to avoid actual API calls
|
|
async def mock_run_single_shot(prompt):
|
|
return f"Response to: {prompt}"
|
|
|
|
with patch.object(context.app, "run_single_shot", mock_run_single_shot):
|
|
context.response = asyncio.run(context.app.run_single_shot(prompt))
|
|
|
|
|
|
@then("I should receive a response from the application")
|
|
def step_impl(context):
|
|
assert context.response is not None
|
|
assert "Response to:" in context.response
|
|
|
|
|
|
@when("I start an interactive session with the application")
|
|
def step_impl(context):
|
|
async def mock_start_session(history_file=None):
|
|
return None
|
|
|
|
with patch.object(context.app, "start_interactive_session", mock_start_session):
|
|
context.session_started = True
|
|
asyncio.run(context.app.start_interactive_session())
|
|
|
|
|
|
@then("the interactive session should be started")
|
|
def step_impl(context):
|
|
assert context.session_started is True
|
|
|
|
|
|
@when("I try to run the application without loading configuration")
|
|
def step_impl(context):
|
|
try:
|
|
if hasattr(context.app, "run_single_shot"):
|
|
context.result = asyncio.run(context.app.run_single_shot("Hello"))
|
|
else:
|
|
context.result = context.app.run()
|
|
context.exception = None
|
|
except Exception as e:
|
|
context.exception = e
|
|
|
|
|
|
@then("an appropriate application error should be raised")
|
|
def step_impl(context):
|
|
assert context.exception is not None
|
|
assert isinstance(context.exception, CleverAgentsException)
|
|
assert "not configured" in str(context.exception).lower()
|
|
|
|
|
|
@when("I try to load invalid configuration")
|
|
def step_impl(context):
|
|
# Create a temporary configuration file with invalid content
|
|
context.temp_dir = tempfile.TemporaryDirectory()
|
|
config_path = Path(context.temp_dir.name) / "invalid_config.yaml"
|
|
|
|
# Create an invalid configuration (missing required fields)
|
|
config = {
|
|
"agents": {
|
|
"test_agent": {
|
|
# Missing "type" field
|
|
"config": {}
|
|
}
|
|
}
|
|
# Missing "routing" section
|
|
}
|
|
|
|
with open(config_path, "w") as f:
|
|
yaml.dump(config, f)
|
|
|
|
try:
|
|
context.app.load_configuration([config_path])
|
|
context.error = None
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("a configuration error should be raised for the application")
|
|
def step_impl(context):
|
|
assert context.error is not None
|
|
assert "configuration" in str(context.error).lower()
|
|
|
|
|
|
@then("a specific application error should be raised")
|
|
def step_impl(context):
|
|
assert (
|
|
hasattr(context, "exception") and context.exception is not None
|
|
), "No exception was captured"
|
|
assert isinstance(
|
|
context.exception, (ConfigurationError, ExecutionError)
|
|
), f"Expected ConfigurationError or ExecutionError but got {type(context.exception).__name__}"
|
|
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
from cleveragents.core.application import CleverAgentsApp as Application
|
|
from cleveragents.core.exceptions import ConfigurationError
|
|
from cleveragents.core.exceptions import ExecutionError
|
|
|
|
|
|
@given("an application with configuration loaded")
|
|
def step_impl(context):
|
|
# Setup application with configuration loaded
|
|
context.app = Application(config={"setting": "value"})
|
|
|
|
|
|
@then("the application should raise a configuration error")
|
|
def step_impl(context):
|
|
# Verify that a configuration error was raised
|
|
assert context.error is not None
|
|
assert isinstance(context.error, ConfigurationError)
|
|
|
|
|
|
"""
|
|
This file contains step definitions for core application features.
|
|
"""
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
|
|
@given("the application is configured correctly")
|
|
def step_configured(context):
|
|
# Setup application with valid configuration
|
|
pass
|
|
|
|
|
|
@given("the application has all required dependencies")
|
|
def step_dependencies(context):
|
|
# Ensure dependencies are installed
|
|
pass
|
|
|
|
|
|
@then("the application should raise an error about missing configuration")
|
|
def step_verify_error(context):
|
|
# Verify that correct error is raised
|
|
assert context.result.startswith("Error:")
|
|
|
|
|
|
@given("the user initiates the application start")
|
|
def step_initiate_start(context):
|
|
# User initiates start
|
|
pass
|
|
|
|
|
|
@then("the application should not start")
|
|
def step_not_start(context):
|
|
# Check that the app did not start
|
|
assert context.result
|
|
|
|
|
|
import asyncio
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
|
|
@given("the application is configured")
|
|
def step_impl(context):
|
|
context.configured = True
|
|
|
|
|
|
@then("the application should fail to start")
|
|
def step_impl(context):
|
|
assert context.error == "Configuration missing"
|
|
|
|
|
|
@then("a specific error message should be displayed")
|
|
def step_impl(context):
|
|
assert "config" in context.error
|
|
|
|
|
|
import asyncio
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
|
|
@given("the application is properly configured")
|
|
def step_configured(context):
|
|
context.config = {"setting": "value"}
|
|
|
|
|
|
@then("an error should be raised for missing configuration")
|
|
def step_error_missing_config(context):
|
|
if hasattr(context, "error"):
|
|
assert str(context.error) == "Configuration not found"
|
|
else:
|
|
assert context.result == "default configuration applied"
|
|
|
|
|
|
# ... other step definitions can be here ...
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
from cleveragents.core.application import CleverAgentsApp
|
|
from cleveragents.core.exceptions import ApplicationError
|
|
|
|
|
|
@given("a core application with invalid configuration")
|
|
def step_impl(context):
|
|
try:
|
|
context.app = CleverAgentsApp({"config_key": "invalid_value"})
|
|
context.error = None
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@when("the application is started")
|
|
def step_impl(context):
|
|
try:
|
|
context.app.start()
|
|
context.running = True
|
|
except Exception as e:
|
|
context.running = False
|
|
context.error = e
|
|
|
|
|
|
@then("an application error indicating misconfiguration should be raised")
|
|
def step_impl(context):
|
|
assert (
|
|
context.error is not None
|
|
), "No error was raised despite invalid configuration"
|
|
assert isinstance(
|
|
context.error, ApplicationError
|
|
), f"Expected ApplicationError but got {type(context.error).__name__}"
|
|
|
|
|
|
from behave import given
|
|
from behave import then
|
|
from behave import when
|
|
|
|
from cleveragents.core.exceptions import ApplicationError
|
|
|
|
|
|
@given("an application error is triggered")
|
|
def step_impl(context):
|
|
try:
|
|
# Trigger an application error
|
|
raise ApplicationError("Test application error")
|
|
except ApplicationError as error:
|
|
context.error = error
|
|
|
|
|
|
@then("the application error message should be 'Test application error'")
|
|
def step_impl(context):
|
|
assert (
|
|
str(context.error) == "Test application error"
|
|
), f"Expected 'Test application error', got '{context.error}'"
|