use rust_args_parser as ap;
mod common;
use common::*;
use std::env;
use std::ffi::{OsStr, OsString};
fn golden_spec(env_name: &str) -> ap::CmdSpec<'_, Ctx> {
ap::CmdSpec::new("tool")
.help("Multitool root")
.opt(ap::OptSpec::flag("verbose", inc_verbose).short('v').long("verbose").help("Increase verbosity"))
.opt(ap::OptSpec::flag("json", set_json).long("json").help("JSON output"))
.opt(ap::OptSpec::value("jobs", set_jobs).short('j').long("jobs").metavar("N").help("worker threads"))
.opt(
ap::OptSpec::value("limit", set_limit)
.long("limit")
.metavar("N")
.env(env_name)
.default(OsString::from("42")),
)
.subcmd(
ap::CmdSpec::new("repo").help("Repository ops").subcmd(
ap::CmdSpec::new("push")
.help("Push to remote")
.pos(ap::PosSpec::new("REMOTE", set_input).required())
.pos(ap::PosSpec::new("BRANCH", |_, _: &mut Ctx| {}).required())
.pos(ap::PosSpec::new("FILE", push_file).many()),
),
)
}
#[test]
fn golden_complex_cli() {
let envv = env_basic();
env::set_var("APP_LIMIT_1", "99");
let root = golden_spec("APP_LIMIT_1");
let mut ctx = Ctx::default();
let argv = argv(&[
"-vv", "--json", "-j8", "--limit=5", "repo",
"push", "origin", "main", "--", "-nasty.rs",
"a.rs",
"b.rs",
]);
let m = ap::parse(&envv, &root, &argv, &mut ctx).expect("parse ok");
assert_eq!(ctx.verbose, 2);
assert!(ctx.json);
assert_eq!(ctx.jobs, Some(8));
assert_eq!(ctx.limit.as_deref(), Some("5")); assert_eq!(ctx.input.as_deref(), Some(OsStr::new("origin")));
assert_eq!(ctx.files, vec![OsString::from("-nasty.rs"), OsString::from("a.rs"), OsString::from("b.rs"),]);
assert_eq!(m.leaf_path(), vec!["repo", "push"]);
let v = m.view();
assert_eq!(v.pos_one("BRANCH").unwrap(), OsStr::new("main"));
let rootv = m.at(&[]);
assert!(rootv.is_set_from("limit", ap::Source::Cli));
assert!(rootv.is_set_from("json", ap::Source::Cli));
assert!(rootv.is_set_from("verbose", ap::Source::Cli));
}
#[test]
fn golden_complex_cli_env_overlay() {
let envv = env_basic();
std::env::set_var("APP_LIMIT_2", "77");
let root = golden_spec("APP_LIMIT_2");
let mut ctx = Ctx::default();
let argv = argv(&["-v", "repo", "push", "o", "m", "--", "f1"]);
let m = ap::parse(&envv, &root, &argv, &mut ctx).unwrap();
assert_eq!(ctx.verbose, 1);
assert_eq!(ctx.limit.as_deref(), Some("77"));
let rootv = m.at(&[]);
assert!(rootv.is_set_from("limit", ap::Source::Env));
}