use anyhow::Result;
use std::collections::HashMap;
use tracing::{error, info};
pub mod agent;
pub mod builder;
pub mod checker;
pub mod config;
pub mod function;
pub mod loader;
pub mod registry;
pub mod tool;
pub use agent::Agent;
pub use builder::Builder;
pub use checker::Checker;
pub use config::Config;
pub use function::FunctionDeclaration;
pub use loader::Loader;
pub use registry::Registry;
pub use tool::Tool;
pub struct TestRunner {
config: Config,
registry: Registry,
}
impl TestRunner {
pub fn new(config: &Config) -> Self {
Self {
config: config.clone(),
registry: Registry::new(),
}
}
pub async fn run_all(&mut self) -> Result<TestResults> {
info!("Running all tests...");
self.registry.load_tools(&self.config.tool_dirs).await?;
self.registry.load_agents(&self.config.agent_dirs).await?;
let mut results = TestResults::default();
for tool_name in self.registry.list_tools() {
let result = self.run_tool_test(&tool_name).await?;
results.add_tool_result(tool_name, result);
}
for agent_name in self.registry.list_agents() {
let result = self.run_agent_test(&agent_name).await?;
results.add_agent_result(agent_name, result);
}
Ok(results)
}
pub async fn run_suite(&mut self, suite: &str) -> Result<TestResults> {
match suite {
"tools" => self.run_tool_tests().await,
"agents" => self.run_agent_tests().await,
"integration" => self.run_integration_tests().await,
_ => anyhow::bail!("Unknown test suite: {}", suite),
}
}
async fn run_tool_tests(&mut self) -> Result<TestResults> {
self.registry.load_tools(&self.config.tool_dirs).await?;
let mut results = TestResults::default();
for tool_name in self.registry.list_tools() {
let result = self.run_tool_test(&tool_name).await?;
results.add_tool_result(tool_name, result);
}
Ok(results)
}
async fn run_agent_tests(&mut self) -> Result<TestResults> {
self.registry.load_agents(&self.config.agent_dirs).await?;
let mut results = TestResults::default();
for agent_name in self.registry.list_agents() {
let result = self.run_agent_test(&agent_name).await?;
results.add_agent_result(agent_name, result);
}
Ok(results)
}
async fn run_integration_tests(&self) -> Result<TestResults> {
info!("Running integration tests...");
Ok(TestResults::default())
}
async fn run_tool_test(&self, tool: &str) -> Result<TestResult> {
info!(tool = %tool, "Running test for tool");
Ok(TestResult {
passed: true,
duration: std::time::Duration::from_millis(100),
output: format!("Tool {} test passed", tool),
})
}
async fn run_agent_test(&self, agent: &str) -> Result<TestResult> {
info!(agent = %agent, "Running test for agent");
Ok(TestResult {
passed: true,
duration: std::time::Duration::from_millis(200),
output: format!("Agent {} test passed", agent),
})
}
}
#[derive(Debug, Default)]
pub struct TestResults {
tool_results: HashMap<String, TestResult>,
agent_results: HashMap<String, TestResult>,
}
impl TestResults {
pub fn add_tool_result(&mut self, tool_name: String, result: TestResult) {
self.tool_results.insert(tool_name, result);
}
pub fn add_agent_result(&mut self, agent_name: String, result: TestResult) {
self.agent_results.insert(agent_name, result);
}
pub fn print_summary(&self) {
info!("Test Results Summary:");
let total_tools = self.tool_results.len();
let passed_tools = self.tool_results.values().filter(|r| r.passed).count();
info!("Tools: {}/{} passed", passed_tools, total_tools);
let total_agents = self.agent_results.len();
let passed_agents = self.agent_results.values().filter(|r| r.passed).count();
info!("Agents: {}/{} passed", passed_agents, total_agents);
if passed_tools < total_tools || passed_agents < total_agents {
error!("Failed tests:");
for (tool, result) in &self.tool_results {
if !result.passed {
error!(" Tool '{}': {}", tool, result.output);
}
}
for (agent, result) in &self.agent_results {
if !result.passed {
error!(" Agent '{}': {}", agent, result.output);
}
}
}
}
}
#[derive(Debug)]
pub struct TestResult {
pub passed: bool,
pub duration: std::time::Duration,
pub output: String,
}