mirror of
https://github.com/hanzoai/mcp.git
synced 2026-10-15 12:30:12 +00:00
test_shell_tools and test_think_tools have not built since the shell->exec
consolidation, so `cargo test` was red and 46 tests were silently not running.
Nothing here is a new assertion — each change follows the tool's live contract,
read off the published 1.1.22 binary rather than guessed:
shell ShellTool -> ExecTool, ProcToolArgs -> ExecToolArgs. Pure rename;
all 16 pass untouched.
think ThinkTool::execute returns Value, not String, and HIP-0300 moved the
payload under "data". Help reports the tool as "tool", not "name".
Tests whose subject no longer exists are deleted, not rewritten to pass:
critic/review with focus, code_snippets, file_paths and work_description (11);
the timestamp and examples keys (2); action-less auto-detect, which now falls
through to help (1).
browser: playwright_available -> driver_running, its successor since the tool
moved to a CDP driver. That file compiled, so this one was failing, not skipped.
351 pass, 0 fail: lib 223, browser 28, fs 27, search 28, memory 22, shell 16,
think 5, research 2. tests/ is excluded from the package, so 1.1.22's contents
are unchanged and no version bump is warranted.
Co-authored-by: Hanzo Dev <[email protected]>
135 lines
4.1 KiB
Rust
135 lines
4.1 KiB
Rust
//! Think/Reasoning Tools Tests - 1:1 parity with Python think tests
|
|
//!
|
|
//! Tests for think tool covering:
|
|
//! - Tool properties and metadata
|
|
//! - Think action (record thoughts)
|
|
//! - Critic action (critical analysis)
|
|
//! - Review action (balanced code review)
|
|
//! - Review focus areas
|
|
//! - Thought persistence within session
|
|
|
|
use hanzo_mcp::tools::{ThinkTool, ThinkToolArgs};
|
|
|
|
/// Test think tool properties
|
|
#[test]
|
|
fn test_think_tool_properties() {
|
|
let tool = ThinkTool::new();
|
|
// Tool exists and is properly initialized
|
|
assert!(true);
|
|
}
|
|
|
|
/// Test think help action
|
|
#[tokio::test]
|
|
async fn test_think_help_action() {
|
|
let tool = ThinkTool::new();
|
|
let args = ThinkToolArgs {
|
|
action: Some("help".to_string()),
|
|
..Default::default()
|
|
};
|
|
|
|
let result = tool.execute(args).await;
|
|
assert!(result.is_ok());
|
|
|
|
let output = result.unwrap();
|
|
let json = output["data"].clone(); // HIP-0300 envelope: payload under "data"
|
|
|
|
assert!(json.get("actions").is_some());
|
|
assert_eq!(json["tool"], "think");
|
|
}
|
|
|
|
/// Test think action - basic thought recording
|
|
#[tokio::test]
|
|
async fn test_think_basic() {
|
|
let tool = ThinkTool::new();
|
|
let args = ThinkToolArgs {
|
|
action: Some("think".to_string()),
|
|
thought: Some(
|
|
"Considering approach A vs B for implementing the feature.\n\
|
|
A: More performant but complex\n\
|
|
B: Simpler but slower"
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
};
|
|
|
|
let result = tool.execute(args).await;
|
|
assert!(result.is_ok());
|
|
|
|
let output = result.unwrap();
|
|
let json = output["data"].clone(); // HIP-0300 envelope: payload under "data"
|
|
|
|
assert!(json["recorded"].as_bool().unwrap());
|
|
assert!(json.get("id").is_some());
|
|
assert!(json["thought"].as_str().unwrap().contains("approach A vs B"));
|
|
}
|
|
|
|
/// Test think action - auto-detect from thought parameter
|
|
/// Test critic action - basic critical analysis
|
|
/// Test critic action - auto-detect from analysis parameter
|
|
/// Test critic action - section parsing
|
|
/// Test review action - basic code review
|
|
/// Test review action - auto-detect from work_description parameter
|
|
/// Test review action - with code snippets
|
|
/// Test review action - with file paths
|
|
/// Test review action - with additional context
|
|
/// Test all review focus areas
|
|
/// Test review default focus (GENERAL)
|
|
/// Test thought persistence within session
|
|
#[tokio::test]
|
|
async fn test_thought_persistence() {
|
|
let tool = ThinkTool::new();
|
|
|
|
// Record multiple thoughts
|
|
for i in 1..=3 {
|
|
let args = ThinkToolArgs {
|
|
action: Some("think".to_string()),
|
|
thought: Some(format!("Thought number {}", i)),
|
|
..Default::default()
|
|
};
|
|
let result = tool.execute(args).await;
|
|
assert!(result.is_ok());
|
|
|
|
let output = result.unwrap();
|
|
let json = output["data"].clone(); // HIP-0300 envelope: payload under "data"
|
|
|
|
// Each thought should get a unique, incrementing ID
|
|
assert_eq!(json["id"].as_i64().unwrap(), i);
|
|
}
|
|
}
|
|
|
|
/// Test action aliases
|
|
/// Test timestamp format
|
|
/// Test complex thought with multiline content
|
|
#[tokio::test]
|
|
async fn test_complex_thought() {
|
|
let tool = ThinkTool::new();
|
|
let args = ThinkToolArgs {
|
|
action: Some("think".to_string()),
|
|
thought: Some(
|
|
r#"Feature Implementation Planning
|
|
- New code search feature requirements:
|
|
* Search for code patterns across multiple files
|
|
* Identify function usages and references
|
|
* Analyze import relationships
|
|
- Implementation considerations:
|
|
* Need to leverage existing search mechanisms
|
|
* Should use regex for pattern matching
|
|
- Design approach:
|
|
1. Create new CodeSearcher class
|
|
2. Implement core pattern matching
|
|
3. Add result formatting methods"#
|
|
.to_string(),
|
|
),
|
|
..Default::default()
|
|
};
|
|
|
|
let result = tool.execute(args).await;
|
|
assert!(result.is_ok());
|
|
|
|
let output = result.unwrap();
|
|
let json = output["data"].clone(); // HIP-0300 envelope: payload under "data"
|
|
|
|
assert!(json["recorded"].as_bool().unwrap());
|
|
assert!(json["thought"].as_str().unwrap().contains("CodeSearcher"));
|
|
}
|