223 lines
6.5 KiB
Rust
223 lines
6.5 KiB
Rust
/*
|
|
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
*
|
|
* This file is part of SPD.
|
|
*
|
|
* SPD is free software: you can redistribute it and/or modify it under the
|
|
* terms of the GNU Lesser General Public License as published by the Free
|
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version.
|
|
*
|
|
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* This file incorporates work covered by the following copyright and permission
|
|
* notice:
|
|
*
|
|
* Copyright 2017 Douman
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
use crate::env::args::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>,
|
|
}
|
|
|
|
|
|
#[derive(Debug, Args)]
|
|
///my_exe 0.1.0
|
|
///About my program
|
|
///
|
|
///About my program
|
|
struct MyArgs {
|
|
#[arg(short, long, required)]
|
|
///Required argument
|
|
required: u32,
|
|
|
|
#[arg(short, long)]
|
|
///Optional argument
|
|
optional: Option<u32>,
|
|
|
|
#[arg(short, long)]
|
|
///About this flag
|
|
flag: bool,
|
|
|
|
#[arg(long = "verbose")]
|
|
///Verbose mode
|
|
verbose: bool,
|
|
|
|
#[arg(short = "v", long = "velocity", default_value = "42")]
|
|
///This is felocity. Default value is 42.
|
|
speed: u32,
|
|
|
|
#[arg(short = "g", long = "gps")]
|
|
///GPS coordinates.
|
|
gps: Vec<u32>,
|
|
|
|
#[arg(required)]
|
|
///To store path
|
|
path: String,
|
|
|
|
#[arg(required)]
|
|
///To store path 2
|
|
path2: String,
|
|
|
|
///To store rest of paths
|
|
remain_paths: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Args)]
|
|
///My subcommand
|
|
enum BigSubArgs {
|
|
///my arguments
|
|
MyArgs(MyArgs),
|
|
///test args
|
|
Test(Test2),
|
|
}
|
|
|
|
#[derive(Debug, Args)]
|
|
struct BigArgs {
|
|
#[arg(long = "verbose")]
|
|
///Verbose mode
|
|
verbose: bool,
|
|
#[arg(sub)]
|
|
cmd: BigSubArgs,
|
|
}
|
|
|
|
#[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_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_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::RequiredArgMissing("cmd")));
|
|
}
|
|
|
|
#[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], "-");
|
|
}
|
|
|