This repository has been archived on 2023-07-03. You can view files and clone it, but cannot push or open issues or pull requests.
spd/tests/args.rs

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], "-");
}