//! `read` 工具的单元测试。 //! Unit tests for the `read` tool. use focus_core::tool::Tool; use focus_json::JsonValue; use focus_tools::ReadTool; use std::fs; use std::path::PathBuf; fn temp_dir(tag: &str) -> PathBuf { let d = std::env::temp_dir().join(format!("focus-tools-read-{}-{}", tag, std::process::id())); let _ = fs::remove_dir_all(&d); fs::create_dir_all(&d).unwrap(); d } #[test] fn reads_file() { let dir = temp_dir("reads"); fs::write(dir.join("a.txt"), "line1\nline2\nline3\n").unwrap(); let tool = ReadTool::new(&dir); let mut args = JsonValue::obj(); args.insert("path", "a.txt".into()).ok(); let r = tool.execute("id", &args, None).unwrap(); let text = r.content[0].as_text().unwrap().text.clone(); assert_eq!(text, "line1\nline2\nline3\n"); } #[test] fn reads_line_range() { let dir = temp_dir("range"); fs::write(dir.join("a.txt"), "l1\nl2\nl3\nl4\n").unwrap(); let tool = ReadTool::new(&dir); let mut args = JsonValue::obj(); args.insert("path", "a.txt".into()).ok(); args.insert("startLine", 2u64.into()).ok(); args.insert("endLine", 3u64.into()).ok(); let r = tool.execute("id", &args, None).unwrap(); let text = r.content[0].as_text().unwrap().text.clone(); assert_eq!(text, "l2\nl3"); } #[test] fn missing_file_is_an_error_result() { let dir = temp_dir("missing"); let tool = ReadTool::new(&dir); let mut args = JsonValue::obj(); args.insert("path", "nope.txt".into()).ok(); // 可预期错误以 Err 返回(agent 循环会将其编码为错误结果)。 // Expected errors surface as Err (the agent loop encodes them as error // results). let err = tool.execute("id", &args, None).unwrap_err().to_string(); assert!(err.contains("nope.txt"), "got: {}", err); } #[test] fn binary_file_is_rejected() { let dir = temp_dir("bin"); fs::write(dir.join("b.bin"), [0u8, 1, 2, 3]).unwrap(); let tool = ReadTool::new(&dir); let mut args = JsonValue::obj(); args.insert("path", "b.bin".into()).ok(); let r = tool.execute("id", &args, None).unwrap(); assert!(r.content[0] .as_text() .map(|t| t.text.contains("binary")) .unwrap_or(false)); } #[test] fn absolute_path_works() { let dir = temp_dir("abs"); let abs = dir.join("x.txt"); fs::write(&abs, "hi").unwrap(); let tool = ReadTool::new(&dir); let mut args = JsonValue::obj(); args.insert("path", abs.display().to_string().into()).ok(); let r = tool.execute("id", &args, None).unwrap(); let text = r.content[0].as_text().unwrap().text.clone(); assert_eq!(text, "hi"); }