getopt2 0.1.0

Zero dependency strict command line argument parser
Documentation
/*
 * Copyright (c) Radim Kolar 2013, 2018, 2023.
 * SPDX-License-Identifier: MIT
 *
 * getopt2 library is licensed under MIT license:
 *   https://spdx.org/licenses/MIT.html
*/

use crate::new;

/** converts iterable &str into String Vec */
fn toStringVec<'a>(iter: impl IntoIterator<Item = &'a str>) -> Vec<String> {
   iter.into_iter().map(|s| s.to_string()).collect()
}

//  basic getopt parsing

#[test]
fn basic_no_options() {
   let g = new(toStringVec(["one", "two"]), "a");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 2);
   assert_eq!(g.options.len(), 0);
}

#[test]
fn basic_one_option_without_arg() {
   let g = new(toStringVec(["one", "two", "-a"]), "a".to_string());
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 2);
   assert_eq!(g.options.len(), 1);
   assert_eq!(g.options.get(&'a'), Some(&"".to_string()));
}

#[test]
fn basic_one_option_with_arg() {
   let g = new(toStringVec(["one", "-a", "two"]), "a:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.options.get(&'a'), Some(&"two".to_string()));
   assert_eq!(g.arguments, toStringVec(["one"]));
}

#[test]
fn basic_two_options_without_arg() {
   let g = new(toStringVec(["one", "-a", "-b", "two"]), "ab");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.options.get(&'a'), Some(&"".to_string()));
   assert_eq!(g.options.get(&'b'), Some(&"".to_string()));
   assert_eq!(g.arguments, toStringVec(["one", "two"]));
}

#[test]
fn basic_two_option_with_missing_arg() {
   let g = new(toStringVec(["one", "two", "-c"]), "c:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["one", "two", "-c"]));
   assert_eq!(g.options.len(), 0);
}

#[test]
fn basic_question_mark_option_without_arg() {
   let g = new(toStringVec(["-?"]), "?".to_string());
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 0);
   assert_eq!(g.options.len(), 1);
   assert_eq!(g.options.get(&'?'), Some(&"".to_string()));
}

//  advanced getopt parsing

#[test]
fn advanced_dash_without_an_option() {
   let g = new(toStringVec(["one", "-", "two"]), "ab");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["one", "-", "two"]));
   assert_eq!(g.options.len(), 0);
}

#[test]
fn advanced_semi_start_plus_qmark() {
   let g = new(toStringVec(["one", "-a", "two", "three", "-?"]), ":a:b:?");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["one", "three"]));
   assert_eq!(g.options.get(&'a'), Some(&"two".to_string()));
   assert_eq!(g.options.get(&'b'), None);
   assert_eq!(g.options.get(&'?'), Some(&"".to_string()));
   assert_eq!(g.option_has_arg.get(&':'), None);
   assert_eq!(g.option_has_arg.len(), 3);
}

// unknown options parsing

#[test]
fn unknown_option_without_arg() {
   let g = new(toStringVec(["one", "two", "-c", "-a"]), "a");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["one", "two", "-c"]));
   assert_eq!(g.options.get(&'a'), Some(&"".to_string()));
   assert_eq!(g.options.get(&'c'), None);
   assert_eq!(g.options.len(), 1);
}

#[test]
fn unknown_option_with_arg() {
   let g = new(toStringVec(["one", "two", "-c", "kalo"]), "a");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["one", "two", "-c", "kalo"]));
   assert_eq!(g.options.get(&'c'), None);
   assert_eq!(g.options.len(), 0);
}

// misc tests

#[test]
fn bad_input_zero_sized_string() {
   let g = new(toStringVec(["one", "two", "-c", ""]), "c");
   assert!(g.is_ok());
}

#[test]
fn bad_input_zero_sized_arg() {
   let g = new(toStringVec(["one", "two", "-c", ""]), "c:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.options.get(&'c'), Some(&"".to_string()));
}

// checks for getopt.len()

#[test]
fn basic_getopt_len() {
   let g = new(toStringVec(["one", "two"]), "a");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 2);
   assert_eq!(g.len(), 2);
   assert_eq!(g.options.len(), 0);
}

// checks for getopt.get()

#[test]
fn basic_getopt_get() {
   let g = new(toStringVec(["one", "-a", "two"]), "a:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.options.get(&'a'), Some(&"two".to_string()));
   assert_eq!(g.get('a'), Some(&"two".to_string()));
}

// checks for getopt.has()

#[test]
fn basic_getopt_has() {
   let g = new(toStringVec(["one", "-a", "two"]), "a:b");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.has('a'), true);
   assert_eq!(g.has('b'), false);
}

// checks for getopt.is_empty()

#[test]
fn basic_getopt_is_empty() {
   let g = new(toStringVec( ["one","-a","two"]), "a:b");
   assert! ( g.is_ok() );
   let g = g.unwrap();
   assert_eq!( g.is_empty(), false);
}

#[test]
fn empty_getopt_is_empty() {
   let g = new(toStringVec( [ ]), "a:b");
   assert! ( g.is_ok() );
   let g = g.unwrap();
   assert_eq!( g.is_empty(), true);
}

#[test]
fn options_only_getopt_is_empty() {
   let g = new(toStringVec( [ "-a", "makrela" ]), "a:b");
   assert! ( g.is_ok() );
   let g = g.unwrap();
   assert_eq!( g.is_empty(), true);
}