use super::*;
#[test]
fn hits_in_long_lines_all_come_back_and_each_carries_its_match() {
let dir = tempfile::tempdir().unwrap();
let room = dir.path().join("hall").join("clerk");
std::fs::create_dir_all(&room).unwrap();
let filler = "x".repeat(30_000);
for at in 0..12 {
std::fs::write(
room.join(format!("run-{at:02}.jsonl")),
format!("{{\"text\":\"{filler} hall/mayor {filler}\"}}\n"),
)
.unwrap();
}
let tool = SearchTool::new(dir.path(), everywhere()).unwrap();
let outcome = tool
.invoke(&call(&[
("text", Value::String("hall/mayor".to_owned())),
("path", Value::String("hall/clerk".to_owned())),
("context", Value::Number(1.into())),
]))
.unwrap();
let map = outcome.result.as_map();
let matches = map["matches"].as_array().unwrap();
assert_eq!(
(map["count"].as_u64(), map["truncated"].as_bool()),
(Some(12), Some(false))
);
assert!(
matches
.iter()
.all(|hit| hit["text"].as_str().unwrap().contains("hall/mayor"))
);
}
#[test]
fn a_search_stopped_at_the_hit_cap_says_so_and_how_to_narrow() {
let dir = tempfile::tempdir().unwrap();
std::fs::create_dir_all(dir.path().join("lab")).unwrap();
std::fs::write(
dir.path().join("lab").join("Many.md"),
"needle\n".repeat(100),
)
.unwrap();
let tool = SearchTool::new(dir.path(), everywhere()).unwrap();
let outcome = tool.invoke(&text("needle")).unwrap();
let map = outcome.result.as_map();
assert_eq!(map["truncated"], Value::Bool(true));
let stopped = map
.get("stopped")
.and_then(Value::as_str)
.unwrap_or_default();
assert!(
stopped.contains("64") && stopped.contains("path"),
"stopped: {stopped:?}"
);
}
#[test]
fn a_hit_on_a_line_wider_than_the_window_is_cut_to_it() {
let dir = tempfile::tempdir().unwrap();
std::fs::create_dir_all(dir.path().join("lab")).unwrap();
let cap = kernel::consts_policy::INTERVAL_CAP_BYTES;
let wide = format!(
"the ledger {}
",
"x".repeat(cap.saturating_mul(2))
);
std::fs::write(dir.path().join("lab").join("Wide.md"), wide).unwrap();
let tool = SearchTool::new(dir.path(), everywhere()).unwrap();
let outcome = tool.invoke(&text("the ledger")).unwrap();
let map = outcome.result.as_map();
let hit = map["matches"][0]["text"].as_str().unwrap();
assert!(
hit.len() <= 2 * hit::LINE_CAP,
"{} bytes came back",
hit.len()
);
assert!(hit.starts_with("the ledger"));
assert!(hit.ends_with(" bytes]"), "the cut is marked");
assert_eq!(map["truncated"], Value::Bool(false));
}