use arg::Args;
#[allow(unused)]
#[derive(Args, Debug)]
struct Test4 {
}
#[allow(unused)]
#[derive(Args, Debug)]
struct Test3 {
paths: Vec<String>,
}
#[allow(unused)]
#[derive(Args, Debug)]
struct Test2 {
#[arg(short = "u")]
u: bool,
paths: Vec<String>,
}
#[allow(unused)]
#[derive(Args, Debug)]
struct BoolOptionArgs {
#[arg(required)]
option: bool,
}
#[derive(Debug, Args)]
#[arg(infer_name)]
struct MyArgs {
#[arg(short, long, required)]
required: u32,
#[arg(short, long)]
optional: Option<u32>,
#[arg(short, long)]
flag: bool,
#[arg(long = "verbose")]
verbose: bool,
#[arg(short = "v", long = "velocity", default_value = "42")]
speed: u32,
#[arg(short = "g", long = "gps")]
gps: Vec<u32>,
#[arg(required)]
path: String,
#[arg(required)]
path2: String,
remain_paths: Vec<String>,
}
#[derive(Debug, Args)]
enum BigSubArgs {
MyArgs(MyArgs),
Test(Test2),
}
#[derive(Debug, Args)]
struct BigArgs {
#[arg(long = "verbose")]
verbose: bool,
#[arg(sub)]
cmd: BigSubArgs,
}
#[test]
fn should_assert_help() {
const EXPECTED: &str = r#"arg 0.4.2
About my program
About my program
USAGE: [OPTIONS] <path> <path2> [remain_paths]...
OPTIONS:
-h, --help Prints this help information
-r, --required <required> Required argument
-o, --optional <optional> Optional argument
-f, --flag About this flag
--verbose Verbose mode
-v, --velocity <speed> This is felocity. Default value is 42.
-g, --gps <gps>... GPS coordinates.
ARGS:
<path> To store path
<path2> To store path 2
<remain_paths>... To store rest of paths
"#;
assert_eq!(MyArgs::HELP, EXPECTED);
}
#[test]
fn should_error_on_missing_args() {
let result = MyArgs::from_text("-f --verbose path1").unwrap_err();
assert_eq!(result, arg::ParseError::RequiredArgMissing("required"));
let result = MyArgs::from_text("-f -r 5 --verbose path1").unwrap_err();
assert_eq!(result, arg::ParseError::RequiredArgMissing("path2"));
let result = MyArgs::from_text("-f -r 5 --verbose").unwrap_err();
assert_eq!(result, arg::ParseError::RequiredArgMissing("path"));
}
#[test]
fn should_error_on_missing_flag_value() {
let result = MyArgs::from_text("-f -r").unwrap_err();
assert_eq!(result, arg::ParseError::MissingValue("required"));
}
#[test]
fn should_error_on_missing_option_bool() {
let result = BoolOptionArgs::from_text("").unwrap_err();
assert_eq!(result, arg::ParseError::RequiredArgMissing("option"));
}
#[test]
fn should_error_on_invalid_flag_value() {
let result = MyArgs::from_text("-f -r gg").unwrap_err();
assert_eq!(result, arg::ParseError::InvalidFlagValue("required", "gg"));
}
#[test]
fn should_handle_all_flags() {
let result = MyArgs::from_text("-f -r 5 --verbose -v 32 -g 1 --gps 55 path1 path2 rest1 rest2").unwrap();
assert!(result.flag);
assert!(result.verbose);
assert_eq!(result.optional, None);
assert_eq!(result.required, 5);
assert_eq!(result.speed, 32);
assert_eq!(result.gps, &[1, 55]);
assert_eq!(result.path, "path1");
assert_eq!(result.path2, "path2");
assert_eq!(result.remain_paths, &["rest1", "rest2"]);
let result = MyArgs::from_text("-f -r 5 --verbose -o 13 -v 32 -g 1 --gps 55 path1 path2 rest1 rest2").unwrap();
assert!(result.flag);
assert!(result.verbose);
assert_eq!(result.optional, Some(13));
assert_eq!(result.required, 5);
assert_eq!(result.speed, 32);
assert_eq!(result.gps, &[1, 55]);
assert_eq!(result.path, "path1");
assert_eq!(result.path2, "path2");
assert_eq!(result.remain_paths, &["rest1", "rest2"]);
}
#[test]
fn should_fail_missing_sub_command() {
let result = BigArgs::from_text("--verbose").unwrap_err();
println!("result={result}");
assert_eq!(result, arg::ParseKind::Top(arg::ParseError::HelpRequested("Missing command, possible values: [my-args, test]\nSee 'help' for details")));
}
#[test]
fn should_fail_invalid_sub_command() {
let result = BigArgs::from_text("--verbose my-invalid-args -f -r 5 --verbose -v 32 -g 1 --gps 55 path1 path2 rest1 rest2").unwrap_err();
assert_eq!(result, arg::ParseKind::Top(arg::ParseError::InvalidArgValue("cmd", "my-invalid-args")));
}
#[test]
fn should_fail_sub_command_with_wrong_args() {
let result = BigArgs::from_text("--verbose my-args -f -r 5 --verbose -v 32 -g 1 --gps lolka path1 path2 rest1 rest2").unwrap_err();
assert_eq!(result, arg::ParseKind::Sub("my-args", arg::ParseError::InvalidFlagValue("gps", "lolka")));
}
#[test]
fn should_handle_all_flags_as_sub_command() {
let result = BigArgs::from_text("--verbose my-args -f -r 5 --verbose -v 32 -g 1 --gps 55 path1 path2 rest1 rest2").unwrap();
assert!(result.verbose);
let result = match result.cmd {
BigSubArgs::MyArgs(args) => args,
unexpected => panic!("invalid sub command result: {:?}", unexpected),
};
assert!(result.flag);
assert!(result.verbose);
assert_eq!(result.optional, None);
assert_eq!(result.required, 5);
assert_eq!(result.speed, 32);
assert_eq!(result.gps, &[1, 55]);
assert_eq!(result.path, "path1");
assert_eq!(result.path2, "path2");
assert_eq!(result.remain_paths, &["rest1", "rest2"]);
let result = BigArgs::from_text("--verbose test -u path1 path2 rest1 rest2").unwrap();
assert!(result.verbose);
let result = match result.cmd {
BigSubArgs::Test(args) => args,
unexpected => panic!("invalid sub command result: {:?}", unexpected),
};
assert!(result.u);
assert_eq!(result.paths, &["path1", "path2", "rest1", "rest2"]);
}
#[test]
fn should_supply_default_value() {
let result = MyArgs::from_text("-f -r 5 --verbose -g 1 --gps 55 path1 path2 rest1 rest2").unwrap();
assert_eq!(result.speed, 42);
}
#[test]
fn shoukd_handle_dash() {
let result = MyArgs::from_text("-f -r 5 --verbose -g 1 --gps 55 path1 path2 rest1 -").unwrap();
assert_eq!(result.remain_paths[1], "-");
}