use semlith::{Semlith, fleet::Fleet, graph::Symbol, store};
use std::io::Cursor;
const KEY: &str = r"\\?\C:\work\api\src\lock.rs";
fn fixture(dir: &std::path::Path) {
let mut s = Semlith::open(dir, None).unwrap();
s.quiet = true;
let db = s.db();
store::read_only(db, false).unwrap();
let file = store::insert_file(db, KEY, "hash", 64, 0).unwrap();
let chunk = store::insert_chunk(db, file, 0, 1, 3, "fn acquire() {}\n").unwrap();
store::insert_symbol(
db,
file,
Some(chunk),
&Symbol {
kind: "function".to_string(),
name: "acquire".to_string(),
qualified: "acquire".to_string(),
start_line: 1,
end_line: 3,
},
)
.unwrap();
store::read_only(db, true).unwrap();
}
fn call(dir: &std::path::Path, tool: &str, args: serde_json::Value) -> String {
let mut fleet = Fleet::open(&[dir.to_path_buf()]).unwrap();
fleet.quiet = true;
let labels = fleet.labels().join(", ");
let fleet = std::sync::Mutex::new(fleet);
let request = serde_json::json!({
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": { "name": tool, "arguments": args },
});
let input = format!("{request}\n");
let mut out = Vec::new();
semlith::mcp::serve(&fleet, &labels, Cursor::new(input.into_bytes()), &mut out).unwrap();
String::from_utf8(out).unwrap()
}
#[test]
fn no_mcp_tool_hands_back_a_verbatim_path() {
let dir = tempfile::tempdir().unwrap();
fixture(dir.path());
for (tool, args) in [
("semlith_files", serde_json::json!({})),
("semlith_symbol", serde_json::json!({ "name": "acquire" })),
(
"semlith_path",
serde_json::json!({ "from": "acquire", "to": "acquire" }),
),
(
"semlith_neighbors",
serde_json::json!({ "name": "acquire" }),
),
] {
let answer = call(dir.path(), tool, args);
assert!(
!answer.contains(r"\\?\") && !answer.contains(r"\\\\?\\"),
"{tool} handed back a verbatim path:\n{answer}"
);
assert!(
!answer.contains("UNC\\"),
"{tool} handed back a UNC verbatim path:\n{answer}"
);
}
}
#[test]
fn the_store_still_holds_the_verbatim_key() {
let dir = tempfile::tempdir().unwrap();
fixture(dir.path());
let s = Semlith::open(dir.path(), None).unwrap();
let paths = store::all_paths(s.db()).unwrap();
assert_eq!(paths, vec![KEY.to_string()]);
}