use std::io::Cursor;
use serde_json::json;
use super::{FrameError, Incoming, read_message, write_message};
#[test]
fn overlong_line_is_refused_and_the_next_line_is_read_whole() -> Result<(), FrameError> {
let long = "x".repeat(200);
let input = format!("{long}\n{{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"ping\"}}\n");
let mut reader = Cursor::new(input.into_bytes());
assert_eq!(
read_message(&mut reader, 64),
Err(FrameError::Overlong { limit: 64 })
);
let next = read_message(&mut reader, 64)?;
assert_eq!(
next,
Some(Incoming::Request {
id: json!(1),
method: "ping".to_owned(),
params: serde_json::Map::new(),
})
);
assert_eq!(read_message(&mut reader, 64)?, None);
Ok(())
}
#[test]
fn a_line_exactly_at_the_limit_is_read() -> Result<(), FrameError> {
let line = "{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}";
let mut reader = Cursor::new(format!("{line}\n").into_bytes());
let message = read_message(&mut reader, line.len() + 1)?;
assert_eq!(
message,
Some(Incoming::Notification {
method: "notifications/initialized".to_owned(),
params: serde_json::Map::new(),
})
);
Ok(())
}
#[test]
fn not_json_and_not_a_request_are_told_apart() {
let mut reader = Cursor::new(b"not json\n".to_vec());
assert!(matches!(
read_message(&mut reader, 64),
Err(FrameError::NotJson { .. })
));
let mut reader =
Cursor::new(b"{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"ping\"}\n".to_vec());
assert_eq!(
read_message(&mut reader, 64),
Err(FrameError::NotRequest {
message: "id is null"
})
);
}
#[test]
fn a_written_message_is_one_line() -> Result<(), std::io::Error> {
let mut out = Vec::new();
write_message(&mut out, &json!({ "text": "two\nlines" }))?;
assert_eq!(out.split_inclusive(|b| *b == b'\n').count(), 1);
assert_eq!(out.last(), Some(&b'\n'));
Ok(())
}