use crate::{App, Error, Result};
pub fn script<A: App>(path: &str) -> Result {
let file = crate::automation::file::parse_file(path)
.map_err(|e| Error::InvalidSettings(format!("{path}: {e}")))?;
let mut session = crate::test::TestSession::<A>::start().allow_diagnostics();
let result = crate::automation::runner::run::<A>(&file, &mut session);
print_summary(path, &result);
if result.is_ok() {
Ok(())
} else {
Err(Error::Startup(format!(
"{} instruction(s) failed in {path}",
result.failures.len()
)))
}
}
pub fn replay<A: App>(path: &str) -> Result {
let mut file = crate::automation::file::parse_file(path)
.map_err(|e| Error::InvalidSettings(format!("{path}: {e}")))?;
file.header.backend = "windowed".to_string();
crate::automation::runner::run_with_backend::<A>(&file)
}
pub fn inspect<A: App>() -> std::result::Result<String, Error> {
let session = crate::test::TestSession::<A>::start().allow_diagnostics();
Ok(session.tree_snapshot())
}
fn print_summary(path: &str, result: &crate::automation::runner::RunResult) {
if result.is_ok() {
eprintln!("{path}: {} instruction(s) passed", result.passed);
return;
}
eprintln!(
"{path}: {} passed, {} failed",
result.passed,
result.failures.len()
);
for (line_no, msg) in &result.failures {
eprintln!(" line {line_no}: {msg}");
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::command::Command;
use crate::event::Event;
use crate::ui::{column, text, window};
use crate::widget::WidgetRegistrar;
struct NoopApp;
impl App for NoopApp {
type Model = ();
fn init() -> (Self::Model, Command) {
((), Command::none())
}
fn update(_m: &mut Self::Model, _e: Event) -> Command {
Command::none()
}
fn view(_m: &Self::Model, _w: &mut WidgetRegistrar) -> crate::ViewList {
window("main")
.title("Noop")
.child(column().child(text("hello")))
.into()
}
}
#[test]
fn inspect_returns_tree_json() {
let snapshot = inspect::<NoopApp>().unwrap();
assert!(
snapshot.contains("\"type\""),
"expected tree JSON: {snapshot}"
);
}
#[test]
fn script_missing_file_errors() {
let err = script::<NoopApp>("/nonexistent/nope.plushie").unwrap_err();
let msg = format!("{err}");
assert!(msg.contains("/nonexistent/nope.plushie"), "got: {msg}");
}
#[test]
fn replay_parse_error_surfaces_before_spawn() {
let path = std::env::temp_dir().join("plushie_cli_replay_parse_error.plushie");
std::fs::write(&path, "app: Noop\nno separator here\n").unwrap();
let err = replay::<NoopApp>(path.to_str().unwrap()).unwrap_err();
assert!(
matches!(err, Error::InvalidSettings(_)),
"expected InvalidSettings, got: {err}"
);
let _ = std::fs::remove_file(&path);
}
}