use super::super::{DETACHED_EXIT, OpEntry, OpRow, Origin, PIPED_UNOBSERVED};
use super::{TAIL, fold, sink};
use std::fs;
use std::path::Path;
use tempfile::tempdir;
fn prompt(ws: &Path) -> OpEntry {
OpEntry {
ts: "1784783961".into(),
argv: vec![
"litany".into(),
"prompt".into(),
"--name".into(),
"gecko".into(),
ws.to_string_lossy().into_owned(),
"goal".into(),
],
cwd: "/proj".into(),
exit: DETACHED_EXIT,
stdout: String::new(),
stderr: String::new(),
origin: Origin::default(),
}
}
#[test]
fn sink_is_named_from_the_ts_and_the_workspace_leaf() {
let root = Path::new("/state");
assert_eq!(
sink(root, "1784783961", Path::new("/ws/cobalt-gecko")),
root.join("detached").join("1784783961-cobalt-gecko.err"),
);
assert_ne!(
sink(root, "17", Path::new("/ws/a")),
sink(root, "17", Path::new("/ws/b")),
);
assert_eq!(
sink(root, "17", Path::new("/")),
root.join("detached").join("17-workspace.err"),
);
}
#[test]
fn fold_surfaces_a_driver_that_died_after_launching() {
let dir = tempdir().unwrap();
let (state, ws) = (dir.path(), dir.path().join("cobalt-gecko"));
let entry = prompt(&ws);
let clean = fold(state, &entry);
assert!(clean.stderr.is_empty());
assert!(
!OpRow::from(&clean).failed(),
"a silent launch is no failure"
);
let path = sink(state, &entry.ts, &ws);
fs::create_dir_all(path.parent().unwrap()).unwrap();
fs::write(&path, "litany: brazen 0.0.2 != 0.0.3\n").unwrap();
let dead = fold(state, &entry);
assert_eq!(dead.stderr, "litany: brazen 0.0.2 != 0.0.3\n");
assert!(
OpRow::from(&dead).failed(),
"captured stderr makes the -2 row a rendered failure (§7.3)"
);
let old_shape = OpEntry {
argv: vec![
"litany".into(),
"prompt".into(),
ws.to_string_lossy().into_owned(),
"goal".into(),
],
..entry.clone()
};
assert_eq!(
fold(state, &old_shape).stderr,
"litany: brazen 0.0.2 != 0.0.3\n"
);
}
#[test]
fn the_fold_carries_the_tail_and_reads_none_of_it() {
let dir = tempdir().unwrap();
let (state, ws) = (dir.path(), dir.path().join("cobalt-gecko"));
let entry = prompt(&ws);
let path = sink(state, &entry.ts, &ws);
fs::create_dir_all(path.parent().unwrap()).unwrap();
let notice = "litany: compaction landing [c-2] superseded — a compaction landed \
since its fork point (ARCH §2.6); the branch continues\n";
fs::write(&path, notice).unwrap();
let folded = fold(state, &entry);
assert_eq!(folded.stderr, notice, "the tail folds in verbatim");
let row = OpRow::from(&folded);
assert!(
row.failed(),
"and a folded tail is the verdict, not the prose"
);
assert!(row.has_output(), "the pane still offers the expansion");
fs::write(&path, "litany: brazen 0.0.2 != 0.0.3\n").unwrap();
assert!(OpRow::from(&fold(state, &entry)).failed());
}
#[test]
fn fold_leaves_every_row_it_is_not_the_authority_for() {
let dir = tempdir().unwrap();
let (state, ws) = (dir.path(), dir.path().join("cobalt-gecko"));
let entry = prompt(&ws);
let path = sink(state, &entry.ts, &ws);
fs::create_dir_all(path.parent().unwrap()).unwrap();
fs::write(&path, "from the sink").unwrap();
let piped = OpEntry {
exit: PIPED_UNOBSERVED,
..entry.clone()
};
assert!(fold(state, &piped).stderr.is_empty());
let legacy = OpEntry {
stderr: "failed to spawn litany".into(),
..entry.clone()
};
assert_eq!(fold(state, &legacy).stderr, "failed to spawn litany");
let truncated_argv = OpEntry {
argv: vec!["litany".into()],
..entry
};
assert!(fold(state, &truncated_argv).stderr.is_empty());
}
#[test]
fn a_long_sink_folds_in_only_its_tail_from_a_line_boundary() {
let dir = tempdir().unwrap();
let (state, ws) = (dir.path(), dir.path().join("noisy"));
let entry = prompt(&ws);
let path = sink(state, &entry.ts, &ws);
fs::create_dir_all(path.parent().unwrap()).unwrap();
let noise = "chatter\n".repeat(2 * TAIL as usize / 8);
fs::write(&path, format!("{noise}the cause\n")).unwrap();
let folded = fold(state, &entry).stderr;
assert!(folded.len() as u64 <= TAIL, "the fold is bounded");
assert!(folded.ends_with("the cause\n"), "the tail is what is kept");
assert!(
folded.starts_with("chatter\n"),
"the clipped head's partial line is dropped: {:?}",
folded.get(..16),
);
}