use super::{append_op, model, world};
use crate::AppModel;
use crate::opslog::{self, DETACHED_EXIT};
use std::fs;
use std::path::Path;
fn prime(m: &AppModel, cwd: &str, exit: i32) {
opslog::append(
m.state_root(),
&opslog::OpEntry {
ts: "TS".into(),
argv: vec!["lernie".into(), "prime".into()],
cwd: cwd.into(),
exit,
stdout: String::new(),
stderr: if exit == 0 {
String::new()
} else {
"unrecognized subcommand\n".into()
},
},
)
.unwrap();
}
#[test]
fn last_failure_projects_only_a_failed_last_op() {
let w = world();
let (_c, mut m) = model(&w);
assert!(m.last_failure().is_none());
append_op(&m);
m.after_lernie_verb();
assert!(m.last_failure().is_none());
opslog::append(
m.state_root(),
&opslog::OpEntry {
ts: "TS".into(),
argv: vec!["lernie".into(), "prime".into()],
cwd: "/proj".into(),
exit: 2,
stdout: String::new(),
stderr: "prime failed\n".into(),
},
)
.unwrap();
m.after_lernie_verb();
let f = m.last_failure().unwrap();
assert_eq!(f.argv, "lernie prime");
assert_eq!(f.stderr_tail, "prime failed");
}
#[test]
fn a_re_run_green_verb_retires_its_stale_failure_from_the_chip() {
let w = world();
let (_c, mut m) = model(&w);
prime(&m, "/w", 2);
m.after_lernie_verb();
assert_eq!(m.activity().errors, 1, "the fresh failure is live");
prime(&m, "/w", 0);
m.after_lernie_verb();
assert_eq!(
m.activity(),
opslog::Activity {
total: 2,
errors: 0
}
);
assert_eq!(m.ops_rows().len(), 2, "the log keeps both lines");
append_op(&m); prime(&m, "/other", 3);
m.after_lernie_verb();
assert_eq!(m.activity().errors, 1);
assert_eq!(m.last_failure().unwrap().argv, "lernie prime");
}
#[test]
fn a_detached_prompt_that_died_after_launch_surfaces_on_the_next_sweep() {
let w = world();
let (_c, mut m) = model(&w);
let ws = Path::new("/ws/cobalt-gecko");
opslog::append(
m.state_root(),
&opslog::OpEntry {
ts: "17".into(),
argv: vec![
"lernie".into(),
"prompt".into(),
ws.to_string_lossy().into_owned(),
"goal".into(),
],
cwd: "/ws".into(),
exit: DETACHED_EXIT,
stdout: String::new(),
stderr: String::new(),
},
)
.unwrap();
m.after_lernie_verb();
assert!(m.last_failure().is_none());
assert!(!m.ops_rows().last().unwrap().failed());
assert!(!m.ops_rows().last().unwrap().has_output());
let sink = opslog::detached::sink(m.state_root(), "17", ws);
fs::create_dir_all(sink.parent().unwrap()).unwrap();
fs::write(&sink, "brazen 0.0.2 refuses 0.0.3\n").unwrap();
m.after_lernie_verb();
let row = m.ops_rows().last().unwrap();
assert!(
row.failed(),
"the dead driver's stderr makes the row a failure"
);
assert!(row.has_output(), "and the pane offers the expansion");
assert_eq!(
m.last_failure().unwrap().stderr_tail,
"brazen 0.0.2 refuses 0.0.3"
);
assert_eq!(
opslog::tail(m.state_root(), 8).len(),
1,
"no line rewritten"
);
}