runa/crates/runa-dap/tests/stdio.rs

91 lines
2.8 KiB
Rust
Raw Normal View History

use std::io::{Cursor, Write};
use std::process::{Command, Stdio};
use runa_dap::framing::{read_frame, write_frame};
use serde_json::{Value, json};
fn run(input: &[u8], args: &[&str]) -> std::process::Output {
let mut child = Command::new(env!("CARGO_BIN_EXE_runa-dap"))
.args(args)
.env_remove("RUNA_CONNECT")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
child.stdin.take().unwrap().write_all(input).unwrap();
child.wait_with_output().unwrap()
}
fn messages(output: &[u8]) -> Vec<Value> {
let mut reader = Cursor::new(output);
let mut messages = Vec::new();
while let Some(message) = read_frame(&mut reader).unwrap() {
messages.push(message);
}
messages
}
#[test]
fn executable_exchanges_standard_frames_and_disconnects_without_a_server() {
let mut input = Vec::new();
write_frame(
&mut input,
&json!({"seq": 1, "type": "request", "command": "initialize"}),
)
.unwrap();
write_frame(
&mut input,
&json!({"seq": 2, "type": "request", "command": "launch"}),
)
.unwrap();
write_frame(
&mut input,
&json!({"seq": 3, "type": "request", "command": "disconnect"}),
)
.unwrap();
let output = run(&input, &[]);
assert!(output.status.success(), "{:?}", output.stderr);
let messages = messages(&output.stdout);
assert_eq!(
messages[0]["body"]["supportsConfigurationDoneRequest"],
true
);
assert_eq!(messages[1]["success"], false);
assert_eq!(messages[2]["success"], true);
assert_eq!(messages[3]["event"], "terminated");
for (index, message) in messages.iter().enumerate() {
assert_eq!(message["seq"], index + 1);
}
}
#[test]
fn executable_reports_bad_framing_on_protocol_and_stderr() {
let output = run(b"Content-Length: 1048577\r\n\r\n", &[]);
assert!(!output.status.success());
assert!(!output.stderr.is_empty());
let messages = messages(&output.stdout);
assert_eq!(messages[0]["event"], "output");
assert!(
messages[0]["body"]["output"]
.as_str()
.unwrap()
.contains("Invalid DAP framing")
);
assert_eq!(messages[1]["event"], "terminated");
}
#[test]
fn cli_documents_connect_and_rejects_nonloopback_addresses() {
let help = run(&[], &["--help"]);
assert!(help.status.success());
let help = String::from_utf8(help.stdout).unwrap();
assert!(help.contains("RUNA_CONNECT"));
assert!(help.contains("127.0.0.1:3737"));
for address in ["0.0.0.0:3737", "192.0.2.1:3737", "invalid"] {
let output = run(&[], &["--connect", address]);
assert!(!output.status.success());
assert!(!output.stderr.is_empty());
}
}