use super::{answered, bridge, server};
use serde_json::json;
#[test]
fn a_server_that_would_not_start_names_the_program_and_no_more_of_the_argv() {
let argv = vec![
"/nonexistent/mcp-server".to_owned(),
"--the-argv-tail".to_owned(),
];
let capture = bridge("fetch", &argv, "{}");
assert_eq!(capture.exit_code, 1);
assert_eq!(capture.stdout, "");
assert!(
capture.stderr.contains("/nonexistent/mcp-server"),
"{capture:?}"
);
assert!(capture.stderr.contains("would not start"), "{capture:?}");
assert!(
!capture.stderr.contains("the-argv-tail"),
"the sentence quoted the argv past its first word: {capture:?}"
);
}
#[test]
fn an_empty_server_argv_is_refused() {
let capture = bridge("fetch", &[], "{}");
assert_eq!(capture.exit_code, 1);
assert!(capture.stderr.contains("argv is empty"), "{capture:?}");
}
#[test]
fn a_server_that_ends_before_the_handshake_says_which_stage() {
let capture = bridge("fetch", &server("exit 0"), "{}");
assert_eq!(capture.exit_code, 1);
assert!(
capture.stderr.contains("ended before answering initialize"),
"{capture:?}"
);
}
#[test]
fn a_transport_failure_names_the_tool_and_not_the_launcher() {
let capture = bridge("fetch", &server("exit 0"), "{}");
assert!(
capture
.stderr
.contains(r#"the MCP server "fetch" ended before answering initialize"#),
"{capture:?}"
);
assert!(
!capture.stderr.contains("/bin/sh"),
"the sentence named the launcher rather than the tool: {capture:?}"
);
}
#[test]
fn an_error_on_the_call_carries_the_servers_own_sentence() {
let capture = answered(
&json!({"jsonrpc": "2.0", "id": 2,
"error": {"code": -32602, "message": "unknown tool: fetch"}})
.to_string(),
);
assert_eq!(capture.exit_code, 1);
assert!(
capture
.stderr
.contains("refused tools/call: unknown tool: fetch"),
"{capture:?}"
);
}
#[test]
fn a_response_carrying_neither_result_nor_error_is_refused() {
let capture = answered(&json!({"jsonrpc": "2.0", "id": 2}).to_string());
assert_eq!(capture.exit_code, 1);
assert!(
capture
.stderr
.contains("it sent neither a result nor an error"),
"{capture:?}"
);
}
#[test]
fn input_that_is_not_a_json_object_is_refused_before_anything_is_spawned() {
for (input, said) in [("", "not JSON"), ("[1, 2]", "not a JSON object")] {
let capture = bridge("fetch", &server("exit 0"), input);
assert_eq!(capture.exit_code, 1, "{input:?}");
assert!(capture.stderr.contains(said), "{input:?}: {capture:?}");
}
}