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 std::io::Result;
use super::getopt;

// Tests for POSIX '+' mode

/** 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()
}

/** runs getopt::new in posix mode */
fn posix(arg: impl IntoIterator<Item = impl AsRef<str>>, optstring: impl AsRef<str>) -> Result<getopt> {
   let opt = optstring.as_ref();
   let posixopt = if opt.starts_with("+") {
      opt.to_owned()
   } else {
      let mut s = String::from("+");
      s.push_str(opt);
      s
   };
   super::new(arg, posixopt)
}

//  basic POSIX getopt parsing

#[test]
fn basic_no_options() {
   let g = posix(["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_at_start_without_arg() {
   let g = posix(["-a", "one", "two"], "a");
   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_at_start_with_arg() {
   let g = posix(["-a", "two", "one"], "a:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 1);
   assert_eq!(g.options.len(), 1);
   assert_eq!(g.options.get(&'a'), Some(&"two".to_string()));
   assert_eq!(g.arguments, toStringVec(["one"]));
}

#[test]
fn basic_one_option_in_middle_without_arg() {
   let g = posix(["one", "-a", "two"], "a");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 3);
   assert_eq!(g.options.len(), 0);
}

#[test]
fn basic_one_option_in_middle_with_arg() {
   let g = posix(["one", "-a", "two"], "a:");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 3);
   assert_eq!(g.options.len(), 0);
}

#[test]
fn basic_two_options_at_start_without_arg() {
   let g = posix(["-a", "-b", "one", "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_options_in_middle_without_arg() {
   let g = posix(["one", "-a", "-b", "two"], "ab");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments.len(), 4);
   assert_eq!(g.options.len(), 0);
}

//  advanced getopt parsing

#[test]
fn advanced_option_without_optional_arg() {
   let g = posix(["-c","-d","yes","-e"], "c::de");
   assert!(g.is_ok());
   let g = g.unwrap();
   assert_eq!(g.arguments, toStringVec(["yes", "-e"]));
   assert_eq!(g.options.get(&'c'), Some(&"".to_string()));
   assert_eq!(g.options.get(&'d'), Some(&"".to_string()));
   assert_eq!(g.options.get(&'e'), None);
   assert_eq!(g.options.len(), 2);
}

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

// misc tests

#[test]
fn bad_input_zero_sized_strings() {
   let g = posix(["one", "two", "-c", ""], "a");
   assert!(g.is_ok());
}