#[derive(Debug, clap::Args)]
pub struct GetArgs {
pub address: String,
}
#[derive(Debug, clap::Args)]
pub struct SetArgs {
pub address: String,
pub value: String,
#[arg(short = 'd', long)]
pub dry_run: bool,
#[arg(short = 'y', long)]
pub yes: bool,
}
#[derive(Debug, clap::Args)]
pub struct UnsetArgs {
pub address: String,
#[arg(short = 'd', long)]
pub dry_run: bool,
#[arg(short = 'y', long)]
pub yes: bool,
}
#[cfg(test)]
mod tests {
use crate::cli::{Cli, Commands};
fn address(argv: &[&str]) -> String {
use clap::Parser as _;
let full: Vec<&str> = ["shep", "get"]
.into_iter()
.chain(argv.iter().copied())
.collect();
let Commands::Get(args) = Cli::try_parse_from(&full)
.unwrap_or_else(|err| panic!("{full:?} must parse: {err}"))
.command
else {
panic!("{full:?} is not `shep get`")
};
args.address
}
#[test]
fn get_takes_one_address_in_any_of_its_shapes() {
assert_eq!(address(&["api"]), "api");
assert_eq!(address(&["api.max_memory"]), "api.max_memory");
assert_eq!(address(&["api.dogs.kelpie.git"]), "api.dogs.kelpie.git");
assert_eq!(address(&["kelpie.worker"]), "kelpie.worker");
}
#[test]
fn bare_get_is_a_usage_error() {
use clap::Parser;
assert!(Cli::try_parse_from(["shep", "get"]).is_err());
}
#[test]
fn get_takes_exactly_one_address() {
use clap::Parser;
assert!(Cli::try_parse_from(["shep", "get", "api.max_memory", "web.max_memory"]).is_err());
}
#[test]
fn set_takes_an_address_a_value_and_two_flags() {
use clap::Parser;
let parse = |argv: &[&str]| match Cli::try_parse_from(argv).unwrap().command {
Commands::Set(args) => args,
other => panic!("expected set, got {other:?}"),
};
let plain = parse(&["shep", "set", "api.max_memory", "512M"]);
assert_eq!(plain.address, "api.max_memory");
assert_eq!(plain.value, "512M");
assert!(!plain.dry_run);
assert!(!plain.yes);
let table = parse(&["shep", "set", "api.dogs.kelpie.git", "{ keep = 1 }"]);
assert_eq!(table.value, "{ keep = 1 }");
let flagged = parse(&[
"shep",
"set",
"kelpie.worker.timeout",
"30",
"--dry-run",
"--yes",
]);
assert!(flagged.dry_run);
assert!(flagged.yes);
}
#[test]
fn set_needs_both_positionals() {
use clap::Parser;
assert!(Cli::try_parse_from(["shep", "set"]).is_err());
assert!(Cli::try_parse_from(["shep", "set", "api.max_memory"]).is_err());
assert!(
Cli::try_parse_from(["shep", "set", "api.max_memory", "1", "2"]).is_err(),
"one value per write is what keeps `shep set api.name a` saying one thing"
);
}
}