//! tool 模块(`Tool` trait 与注册表)的集成测试。 //! Integration tests for the tool module (`Tool` trait and registry). use focus_core::tool::{Tool, ToolEffects, ToolRegistry, ToolResult, ToolUpdateSink}; use focus_core::CoreResult; use focus_json::JsonValue; #[derive(Debug)] struct EchoTool; impl Tool for EchoTool { fn name(&self) -> &str { "echo" } fn description(&self) -> &str { "echoes input" } fn parameters(&self) -> JsonValue { JsonValue::obj() } fn effects(&self) -> ToolEffects { ToolEffects::READ } fn execute( &self, _id: &str, args: &JsonValue, _on_update: Option<&ToolUpdateSink>, ) -> CoreResult { let text = focus_json::to_string(args); Ok(ToolResult::text(text)) } } #[test] fn registry_lookup() { let r = ToolRegistry::with(Box::new(EchoTool)); assert!(r.get("echo").is_some()); assert!(r.get("nope").is_none()); assert_eq!(r.len(), 1); } #[test] fn tool_definitions_shape() { let r = ToolRegistry::with(Box::new(EchoTool)); let defs = r.tool_definitions(); let arr = match &defs { JsonValue::Arr(a) => a, _ => panic!("expected array"), }; let first = &arr[0]; assert_eq!(first.get_str("name"), Some("echo")); assert_eq!(first.get_str("description"), Some("echoes input")); } #[test] fn read_effects_compatible() { assert!(ToolEffects::READ.compatible_with(ToolEffects::READ)); // 写与读不兼容。 // write vs read is not compatible assert!(!ToolEffects::WRITE.compatible_with(ToolEffects::READ)); // 触网/开进程会阻止并行。 // network/process block parallelism assert!(!ToolEffects::NETWORK.compatible_with(ToolEffects::NONE)); assert!(!ToolEffects::PROCESS.compatible_with(ToolEffects::NONE)); }