feat(core): add comprehensive tool definition tests
- Export anthropic::Tool as ApiTool for API tool definitions - Add 6 comprehensive tests for tool schema validation: - test_tool_schema_format: JSON Schema format validation - test_tool_schema_required_params: required/optional param handling - test_to_anthropic_tools: Anthropic API format conversion - test_registry_schemas: ToolRegistry::schemas() method - test_standard_registry_has_all_tools: all 4 tools registered - test_tool_default_values_in_schema: default value handling Closes #22 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
554b2f7f99
commit
d6ac8c8273
2 changed files with 108 additions and 1 deletions
|
|
@ -15,8 +15,8 @@ pub use types::*;
|
|||
pub use anthropic::{
|
||||
AnthropicClient, AnthropicError, Message, Role, ContentBlock,
|
||||
MessagesRequest, MessagesResponse, StreamEvent, StopReason, Usage,
|
||||
Tool as ApiTool, // Anthropic API tool definition format
|
||||
};
|
||||
// Note: anthropic::Tool is a different type from tool::Tool trait
|
||||
pub use tool::{
|
||||
Tool as ToolTrait, ToolRegistry, ToolError, ToolOutput, ToolResult, ParameterDef,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -587,6 +587,7 @@ pub fn create_standard_tool_registry() -> crate::tool::ToolRegistry {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::tool::ToolRegistry;
|
||||
use std::io::Write;
|
||||
use tempfile::TempDir;
|
||||
|
||||
|
|
@ -776,6 +777,112 @@ mod tests {
|
|||
assert!(schema["properties"]["command"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_schema_format() {
|
||||
// Test that schemas follow JSON Schema format
|
||||
let read = ReadTool::new();
|
||||
let schema = read.schema();
|
||||
|
||||
// Check required JSON Schema fields
|
||||
assert_eq!(schema["type"], "object");
|
||||
assert!(schema["properties"].is_object());
|
||||
assert!(schema["required"].is_array());
|
||||
|
||||
// Check that required params are in required array
|
||||
let required = schema["required"].as_array().unwrap();
|
||||
assert!(required.contains(&serde_json::json!("path")));
|
||||
|
||||
// Check property types
|
||||
assert_eq!(schema["properties"]["path"]["type"], "string");
|
||||
assert_eq!(schema["properties"]["offset"]["type"], "number");
|
||||
assert_eq!(schema["properties"]["limit"]["type"], "number");
|
||||
|
||||
// Check descriptions are present
|
||||
assert!(schema["properties"]["path"]["description"].is_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_schema_required_params() {
|
||||
// Verify required vs optional parameter handling
|
||||
let edit = EditTool::new();
|
||||
let schema = edit.schema();
|
||||
|
||||
let required = schema["required"].as_array().unwrap();
|
||||
|
||||
// Required parameters
|
||||
assert!(required.contains(&serde_json::json!("path")));
|
||||
assert!(required.contains(&serde_json::json!("old_string")));
|
||||
assert!(required.contains(&serde_json::json!("new_string")));
|
||||
|
||||
// Optional parameter should not be in required
|
||||
assert!(!required.contains(&serde_json::json!("replace_all")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_anthropic_tools() {
|
||||
// Test conversion to Anthropic API format
|
||||
let mut registry = ToolRegistry::new();
|
||||
registry.register(ReadTool::new());
|
||||
registry.register(WriteTool::new());
|
||||
|
||||
let api_tools = registry.to_anthropic_tools();
|
||||
|
||||
assert_eq!(api_tools.len(), 2);
|
||||
|
||||
// Find read tool
|
||||
let read_tool = api_tools.iter().find(|t| t.name == "read").unwrap();
|
||||
assert_eq!(read_tool.name, "read");
|
||||
assert!(!read_tool.description.is_empty());
|
||||
assert_eq!(read_tool.input_schema["type"], "object");
|
||||
assert!(read_tool.input_schema["properties"]["path"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_registry_schemas() {
|
||||
// Test ToolRegistry::schemas method
|
||||
let mut registry = ToolRegistry::new();
|
||||
registry.register(BashTool::new());
|
||||
registry.register(EditTool::new());
|
||||
|
||||
let schemas = registry.schemas();
|
||||
|
||||
assert_eq!(schemas.len(), 2);
|
||||
|
||||
// Each schema should have name, description, input_schema
|
||||
for schema in &schemas {
|
||||
assert!(schema["name"].is_string());
|
||||
assert!(schema["description"].is_string());
|
||||
assert!(schema["input_schema"]["type"] == "object");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_registry_has_all_tools() {
|
||||
let registry = create_standard_tool_registry();
|
||||
|
||||
// Should have all 4 tools
|
||||
assert_eq!(registry.len(), 4);
|
||||
|
||||
// Check each tool exists
|
||||
let api_tools = registry.to_anthropic_tools();
|
||||
let tool_names: Vec<&str> = api_tools.iter().map(|t| t.name.as_str()).collect();
|
||||
|
||||
assert!(tool_names.contains(&"read"));
|
||||
assert!(tool_names.contains(&"write"));
|
||||
assert!(tool_names.contains(&"edit"));
|
||||
assert!(tool_names.contains(&"bash"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_default_values_in_schema() {
|
||||
// Test that default values are included in schema
|
||||
let read = ReadTool::new();
|
||||
let schema = read.schema();
|
||||
|
||||
// offset has a default value
|
||||
assert_eq!(schema["properties"]["offset"]["default"], 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_bash_tool_echo() {
|
||||
let tool = BashTool::new();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue