use super::{assert_prefixed, noop_editor, with_fx, with_litany_home};
use crate::cmd::{Command, Outcome, skills};
use crate::workspace::fixture;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
fn parse(argv: &[&str]) -> Command {
<crate::cmd::Cli as clap::Parser>::parse_from(argv).command
}
fn run(home: &Path, args: skills::Args) -> Result<Outcome, crate::cmd::Error> {
with_litany_home(home, || {
with_fx("litany", b"", &noop_editor, |fx| skills::run(args, fx)).0
})
}
#[test]
fn the_argv_shape_is_a_workspace_and_an_optional_lineage() {
let Command::Skills(bare) = parse(&["litany", "skills", "/ws"]) else {
panic!("skills takes a workspace")
};
assert_eq!(bare.workspace, PathBuf::from("/ws"));
assert_eq!(bare.config, None);
let Command::Skills(named) = parse(&["litany", "skills", "/ws", "--config", "alt"]) else {
panic!("skills takes --config")
};
assert_eq!(named.config.as_deref(), Some("alt"));
}
#[test]
fn the_product_is_the_census_table() {
let (holder, ws) = fixture::workspace();
let Outcome::Line(table) = run(
&holder.path().join("data"),
skills::Args {
workspace: ws,
config: None,
},
)
.unwrap() else {
panic!("skills prints its census")
};
let mut lines = table.lines();
assert!(lines.next().unwrap().starts_with("SKILL "), "{table}");
let bash = lines
.find(|l| l.starts_with("bash "))
.expect("the shipped pool's bash skill has a row");
assert!(bash.contains("pool"), "{bash}");
assert!(bash.contains("active"), "{bash}");
}
#[test]
fn a_path_that_is_no_workspace_is_declined() {
let tmp = TempDir::new().unwrap();
let e = run(
tmp.path(),
skills::Args {
workspace: tmp.path().join("nope"),
config: None,
},
)
.unwrap_err();
assert_prefixed(e, "skills");
}
#[test]
fn a_lineage_the_workspace_has_not_is_declined() {
let (holder, ws) = fixture::workspace();
let e = run(
&holder.path().join("data"),
skills::Args {
workspace: ws,
config: Some("nosuch".into()),
},
)
.unwrap_err();
assert_prefixed(e, "skills");
}