mod common;
use common::call_tool_raw;
#[tokio::test]
async fn test_edit_replace_not_found_shows_file_preview() {
let cwd = std::env::current_dir().expect("should get cwd");
let temp_dir = tempfile::TempDir::new_in(&cwd).expect("should create temp dir in cwd");
let working_dir = temp_dir
.path()
.to_str()
.expect("temp dir path is valid UTF-8");
let file_name = "test.txt";
let file_path = temp_dir.path().join(file_name);
let content = "line one\nline two\nline three\n";
std::fs::write(&file_path, content).expect("should write file");
let resp = call_tool_raw(
"edit_replace",
serde_json::json!({
"path": file_name,
"old_text": "nonexistent text",
"new_text": "replacement",
"working_dir": working_dir
}),
)
.await;
assert!(
resp["result"]["isError"].as_bool().unwrap_or(false),
"expected error but got success: {resp}"
);
let msg = resp["result"]["content"][0]["text"]
.as_str()
.expect("should have error text");
assert!(
msg.contains("The file begins:"),
"error message should contain 'The file begins:' but got: {msg}"
);
assert!(
msg.contains("line one"),
"error message should contain file content but got: {msg}"
);
assert!(
msg.contains("Nearest match:"),
"error message should contain nearest match hint but got: {msg}"
);
assert!(
!msg.contains(working_dir),
"error message must not contain working_dir path: {msg}"
);
assert!(
!msg.contains(file_name),
"error message must not contain file path: {msg}"
);
}
#[tokio::test]
async fn test_edit_replace_ambiguous_shows_line_numbers() {
let cwd = std::env::current_dir().expect("should get cwd");
let temp_dir = tempfile::TempDir::new_in(&cwd).expect("should create temp dir in cwd");
let working_dir = temp_dir
.path()
.to_str()
.expect("temp dir path is valid UTF-8");
let file_name = "test.txt";
let file_path = temp_dir.path().join(file_name);
let content = "alpha\nbeta\nalpha\n";
std::fs::write(&file_path, content).expect("should write file");
let resp = call_tool_raw(
"edit_replace",
serde_json::json!({
"path": file_name,
"old_text": "alpha",
"new_text": "replacement",
"working_dir": working_dir
}),
)
.await;
assert!(
resp["result"]["isError"].as_bool().unwrap_or(false),
"expected error but got success: {resp}"
);
let msg = resp["result"]["content"][0]["text"]
.as_str()
.expect("should have error text");
assert!(
msg.contains("Occurrences at lines:"),
"error message should contain 'Occurrences at lines:' but got: {msg}"
);
assert!(
msg.contains("2 locations"),
"error message should mention match count but got: {msg}"
);
assert!(
!msg.contains(working_dir),
"error message must not contain working_dir path: {msg}"
);
assert!(
!msg.contains(file_name),
"error message must not contain file path: {msg}"
);
}