focus/crates/focus-transport/tests/transport_tests.rs

97 lines
3.1 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! transport 模块chunked 解码)的集成测试。
//! Integration tests for the transport module (chunked decoding).
use focus_transport::transport::decode_chunked;
#[test]
fn decodes_simple_chunked_body() {
// 两个分块:"Hello" 与 " World",随后是终止分块。
// Two chunks: "Hello" and " World", then terminating chunk.
let body = b"5\r\nHello\r\n6\r\n World\r\n0\r\n\r\n";
let decoded = decode_chunked(body).unwrap();
assert_eq!(decoded, b"Hello World");
}
#[test]
fn decodes_chunk_with_extension() {
let body = b"5;name=value\r\nHello\r\n0\r\n\r\n";
let decoded = decode_chunked(body).unwrap();
assert_eq!(decoded, b"Hello");
}
#[test]
fn decodes_single_chunk() {
let body = b"3\r\nabc\r\n0\r\n\r\n";
assert_eq!(decode_chunked(body).unwrap(), b"abc");
}
// ---- 增量 chunked 解码器 ----
// ---- incremental chunked decoder ------------------------------------------
use focus_transport::transport::ChunkedDecoder;
/// 把所有解码输出合并为一个字符串(测试辅助)。
/// Concatenate all decoded output into one string (test helper).
fn drain(dec: &mut ChunkedDecoder) -> String {
let mut out = Vec::new();
loop {
match dec.take_decoded() {
Some(mut chunk) => out.append(&mut chunk),
None => {
if dec.is_finished() {
break;
}
return String::from_utf8_lossy(&out).to_string();
}
}
}
String::from_utf8_lossy(&out).to_string()
}
#[test]
fn decodes_single_chunk_fed_at_once() {
let mut dec = ChunkedDecoder::new();
dec.feed(b"5\r\nhello\r\n0\r\n\r\n");
assert_eq!(drain(&mut dec), "hello");
}
#[test]
fn decodes_chunk_split_across_feeds() {
// 网络分块与 HTTP 分块不对齐:一次喂一半。
// Network chunks misalign with HTTP chunks: feed half at a time.
let mut dec = ChunkedDecoder::new();
dec.feed(b"5\r\nhe");
assert_eq!(drain(&mut dec), "he");
dec.feed(b"llo\r\n0\r\n\r\n");
assert_eq!(drain(&mut dec), "llo");
}
#[test]
fn decodes_multiple_chunks_and_extension() {
let mut dec = ChunkedDecoder::new();
dec.feed(b"5;name=value\r\nhello\r\n6\r\n world\r\n0\r\n\r\n");
assert_eq!(drain(&mut dec), "hello world");
}
#[test]
fn yields_partial_data_before_terminator() {
let mut dec = ChunkedDecoder::new();
// 第一个分块完整、第二个分块只喂了部分,应先把已解码部分吐出。
// First chunk complete, second partial: yield decoded bytes so far.
dec.feed(b"3\r\nabc\r\n5\r\n12");
assert_eq!(drain(&mut dec), "abc12");
dec.feed(b"345\r\n0\r\n\r\n");
assert_eq!(drain(&mut dec), "345");
}
#[test]
fn decodes_an_sse_stream_in_chunked_framing() {
// 模拟完整 SSE 流chunked 编码)经解码器逐块吐出。
// Simulate a full SSE stream (chunked-encoded) drained through the decoder.
let payload = "event: message_start\r\ndata: {\"type\":\"x\"}\r\n\r\n";
let mut dec = ChunkedDecoder::new();
dec.feed(format!("{:x}\r\n{}\r\n", payload.len(), payload).as_bytes());
dec.feed(b"0\r\n\r\n");
assert_eq!(drain(&mut dec), payload);
}