use super::super::stderr::{TAIL_CHARS as STDERR_TAIL_CHARS, tail as stderr_tail};
use super::*;
fn drive_stderr(
replies: Vec<io::Result<Vec<u8>>>,
stderrs: Vec<Vec<u8>>,
max: u32,
) -> (Result<(), Error>, Vec<u8>) {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("steps/c/001/response.json");
let adapter = StubAdapter::with_stderr(replies, stderrs);
let (result, _, _) = run_with(&path, adapter, retry(max), false);
let log = std::fs::read(path.with_file_name("stderr.log")).unwrap();
(result, log)
}
#[test]
fn a_startup_failure_surfaces_its_stderr_and_names_the_artifact() {
let complaint = b"bz: config /home/u/.config/brazen/config.toml: expected `=`\n";
let (result, log) = drive_stderr(vec![Ok(Vec::new())], vec![complaint.to_vec()], 3);
let err = result.unwrap_err();
let text = err.to_string();
assert!(matches!(err, Error::AdapterHalfStream { .. }));
assert!(text.contains("expected `=`"), "{text}");
assert!(text.contains("stderr.log"), "{text}");
assert_eq!(log, complaint.to_vec());
}
#[test]
fn every_attempt_appends_its_stderr_and_the_last_one_is_quoted() {
let (result, log) = drive_stderr(
vec![Ok(error_stream(ErrorKind::Transport)), Ok(Vec::new())],
vec![
b"first attempt noise\n".to_vec(),
b"fatal: no auth\n".to_vec(),
],
3,
);
let text = result.unwrap_err().to_string();
assert!(text.contains("fatal: no auth"), "{text}");
assert!(!text.contains("first attempt noise"), "{text}");
assert_eq!(log, b"first attempt noise\nfatal: no auth\n".to_vec());
}
#[test]
fn a_clean_run_leaves_an_empty_stderr_artifact() {
let (result, log) = drive_stderr(vec![Ok(text_stream("hi", FinishReason::Stop))], vec![], 3);
result.unwrap();
assert!(log.is_empty(), "an ordinary run says nothing on stderr");
}
#[test]
fn a_silent_half_stream_reads_as_a_genuine_mid_stream_kill() {
let (result, _) = drive_stderr(vec![Ok(Vec::new())], vec![], 3);
assert!(result.unwrap_err().to_string().contains("(empty)"));
}
#[test]
fn the_tail_flattens_lines_and_truncates_from_the_front() {
assert_eq!(stderr_tail(b""), "(empty)");
assert_eq!(stderr_tail(b" \n\n"), "(empty)");
assert_eq!(stderr_tail(b"one\ntwo\n"), "one | two");
let long = "x".repeat(STDERR_TAIL_CHARS) + "-END";
let tail = stderr_tail(long.as_bytes());
assert!(tail.starts_with('…'), "{tail}");
assert!(tail.ends_with("-END"), "{tail}");
assert_eq!(tail.chars().count(), STDERR_TAIL_CHARS + 1);
}