use super::*;
fn wired() -> (Streamed, mpsc::Sender<Chunk>) {
let (tx, rx) = mpsc::channel();
(Streamed::new(Stream::from_rx(rx)), tx)
}
#[test]
fn poll_is_pending_when_nothing_is_buffered() {
let (mut s, _tx) = wired();
assert_eq!(s.poll(), StreamedPoll::Pending);
}
#[test]
fn poll_buffers_a_partial_line_until_its_newline() {
let (mut s, tx) = wired();
tx.send(Chunk::Stdout(b"ab".to_vec())).unwrap();
assert_eq!(s.poll(), StreamedPoll::Pending);
tx.send(Chunk::Stdout(b"c\n".to_vec())).unwrap();
assert_eq!(s.poll(), StreamedPoll::Lines(vec!["abc".to_owned()]));
}
#[test]
fn poll_splits_multiple_and_blank_lines_verbatim() {
let (mut s, tx) = wired();
tx.send(Chunk::Stdout(
b"code: WXYZ\n\nopen https://x/device\n".to_vec(),
))
.unwrap();
assert_eq!(
s.poll(),
StreamedPoll::Lines(vec![
"code: WXYZ".to_owned(),
String::new(),
"open https://x/device".to_owned(),
])
);
}
#[test]
fn poll_truncates_an_overlong_line_at_the_bound() {
let (mut s, tx) = wired();
let mut giant = vec![b'a'; 5000];
giant.push(b'\n');
tx.send(Chunk::Stdout(giant)).unwrap();
let StreamedPoll::Lines(lines) = s.poll() else {
panic!("expected a truncated line");
};
assert_eq!(lines, vec![format!("{}…[truncated]", "a".repeat(4096))]);
}
#[test]
fn poll_flushes_a_trailing_partial_line_at_eof_then_stays_pending() {
let (mut s, tx) = wired();
tx.send(Chunk::Stdout(b"tail".to_vec())).unwrap();
drop(tx);
let done = s.poll();
assert_eq!(
done,
StreamedPoll::Done(StreamedOutcome {
lines: vec!["tail".to_owned()],
exit: -1, stderr: String::new(),
})
);
assert_eq!(s.poll(), StreamedPoll::Pending);
}
#[test]
fn poll_folds_stderr_and_exit_into_the_outcome_row() {
let (mut s, tx) = wired();
tx.send(Chunk::Stderr(b"auth failed\n".to_vec())).unwrap();
tx.send(Chunk::Exited(ExitInfo::Code(2))).unwrap();
assert_eq!(
s.poll(),
StreamedPoll::Done(StreamedOutcome {
lines: Vec::new(), exit: 2,
stderr: "auth failed\n".to_owned(),
})
);
}
#[test]
fn try_next_emits_exit_once_then_stays_pending() {
let (tx, rx) = mpsc::channel::<Chunk>();
drop(tx);
let mut stream = Stream::from_rx(rx);
assert!(matches!(
stream.try_next(),
StreamPoll::Ready(Chunk::Exited(_))
));
assert_eq!(stream.try_next(), StreamPoll::Pending);
}