const MINIMAL_ARGV: &[&str] = &["bugwarden", "--bugzilla-server", "https://bugzilla.example"];
fn pin_environment(cmd: clap::Command) -> clap::Command {
cmd.mut_args(|arg| arg.env(None::<&'static str>))
}
pub fn pinned<C: clap::CommandFactory + clap::FromArgMatches>(argv: &[&str]) -> C {
let matches = pin_environment(C::command())
.try_get_matches_from(argv)
.expect("the harness command line must parse");
C::from_arg_matches(&matches).expect("the harness command line must build a Cli")
}
pub fn assert_the_pin_drops_every_fallback<C: clap::CommandFactory>() {
let mut pinned = pin_environment(C::command());
pinned.build();
let leaking: Vec<String> = pinned
.get_arguments()
.filter_map(clap::Arg::get_env)
.map(|env| env.to_string_lossy().into_owned())
.collect();
assert!(
leaking.is_empty(),
"these environment fallbacks still reach the harness: {leaking:?}"
);
let mut real = C::command();
real.build();
assert!(
real.get_arguments().any(|arg| arg.get_env().is_some()),
"the binary declares no environment fallback at all, so the assertion \
above proves nothing"
);
}
pub fn assert_the_pin_neutralises_a_flag_added_later<C: clap::CommandFactory>() {
let (name, value) = std::env::vars_os()
.next()
.expect("the test process must carry at least one environment variable");
let name: &'static std::ffi::OsStr = Box::leak(name.into_boxed_os_str());
let added_later = || {
clap::Arg::new("added-later")
.long("added-later")
.env(name)
.value_parser(clap::builder::OsStringValueParser::new())
};
let ambient = pin_environment(C::command())
.arg(added_later())
.try_get_matches_from(MINIMAL_ARGV)
.expect("the probe command line must parse");
assert_eq!(
ambient.get_one::<std::ffi::OsString>("added-later"),
Some(&value),
"the probe variable must reach an unpinned field, or this proves nothing"
);
let pinned = pin_environment(C::command().arg(added_later()))
.try_get_matches_from(MINIMAL_ARGV)
.expect("the probe command line must parse");
assert_eq!(
pinned.get_one::<std::ffi::OsString>("added-later"),
None,
"{name:?} reached a pinned field"
);
}