mod common;
#[test]
fn test_search_in_subdir_with_different_cwd() {
let dir = tempfile::tempdir().expect("workspace tempdir");
let src = dir.path().join("src");
std::fs::create_dir(&src).expect("mkdir src");
common::create_test_file(
&src,
"hello.rs",
"fn main() {\n println!(\"needle_g121\");\n}\n",
);
let outer = tempfile::tempdir().expect("outer tempdir");
let output = common::atomwrite()
.current_dir(outer.path())
.args([
"--workspace",
dir.path().to_str().unwrap(),
"search",
"needle_g121",
])
.arg("src")
.output()
.expect("run");
assert!(
output.status.success(),
"search with CWD != workspace must succeed; stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let events = common::parse_ndjson(&output.stdout);
let matches: Vec<_> = events.iter().filter(|e| e["type"] == "match").collect();
assert!(
!matches.is_empty(),
"G121: search must find needle in workspace/src/ even when CWD != workspace; \
events: {events:?}"
);
assert!(
matches[0]["lines"]
.as_str()
.unwrap_or("")
.contains("needle_g121"),
"matched line should contain the needle"
);
}
#[test]
fn test_replace_in_subdir_with_different_cwd() {
let dir = tempfile::tempdir().expect("workspace tempdir");
let src = dir.path().join("src");
std::fs::create_dir(&src).expect("mkdir src");
let target = src.join("rep.rs");
std::fs::write(&target, "old_token_g121(x)\nold_token_g121(y)\n").expect("seed");
let outer = tempfile::tempdir().expect("outer tempdir");
let output = common::atomwrite()
.current_dir(outer.path())
.args([
"--workspace",
dir.path().to_str().unwrap(),
"replace",
"old_token_g121",
"new_token_g121",
])
.arg("src")
.output()
.expect("run");
assert!(
output.status.success(),
"replace with CWD != workspace must succeed; stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let events = common::parse_ndjson(&output.stdout);
let replaced: Vec<_> = events.iter().filter(|e| e["type"] == "replaced").collect();
assert_eq!(
replaced.len(),
1,
"G121: replace must modify the file under workspace/src/; events: {events:?}"
);
assert_eq!(replaced[0]["replacements"], 2);
let content = std::fs::read_to_string(&target).expect("read");
assert!(content.contains("new_token_g121"), "token must be replaced");
assert!(
!content.contains("old_token_g121"),
"old token must be gone"
);
}
#[test]
fn test_search_absolute_path_with_different_cwd() {
let dir = tempfile::tempdir().expect("workspace tempdir");
let sub = dir.path().join("abs");
std::fs::create_dir(&sub).expect("mkdir abs");
common::create_test_file(&sub, "data.txt", "abs_path_marker_g121\n");
let outer = tempfile::tempdir().expect("outer tempdir");
let abs_target = sub.to_str().expect("abs utf8");
let output = common::atomwrite()
.current_dir(outer.path())
.args([
"--workspace",
dir.path().to_str().unwrap(),
"search",
"abs_path_marker_g121",
])
.arg(abs_target)
.output()
.expect("run");
assert!(
output.status.success(),
"search with absolute workspace path and outer CWD must succeed; \
stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let events = common::parse_ndjson(&output.stdout);
let matches: Vec<_> = events.iter().filter(|e| e["type"] == "match").collect();
assert!(
!matches.is_empty(),
"G121: absolute path inside workspace must be found; events: {events:?}"
);
}