From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/getopts/src/tests/mod.rs | 1254 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1254 insertions(+) create mode 100644 vendor/getopts/src/tests/mod.rs (limited to 'vendor/getopts/src/tests') diff --git a/vendor/getopts/src/tests/mod.rs b/vendor/getopts/src/tests/mod.rs new file mode 100644 index 000000000..f1fb39098 --- /dev/null +++ b/vendor/getopts/src/tests/mod.rs @@ -0,0 +1,1254 @@ +use super::each_split_within; +use super::Fail::*; +use super::{HasArg, Name, Occur, Opt, Options, ParsingStyle}; + +#[test] +fn test_split_within() { + fn t(s: &str, i: usize, u: &[String]) { + let v = each_split_within(&(s.to_string()), i); + assert!(v.iter().zip(u.iter()).all(|(a, b)| a == b)); + } + t("", 0, &[]); + t("", 15, &[]); + t("hello", 15, &["hello".to_string()]); + t( + "\nMary had a little lamb\nLittle lamb\n", + 15, + &[ + "Mary had a".to_string(), + "little lamb".to_string(), + "Little lamb".to_string(), + ], + ); + t( + "\nMary had a little lamb\nLittle lamb\n", + ::std::usize::MAX, + &[ + "Mary had a little lamb".to_string(), + "Little lamb".to_string(), + ], + ); +} + +// Tests for reqopt +#[test] +fn test_reqopt() { + let long_args = vec!["--test=20".to_string()]; + let mut opts = Options::new(); + opts.reqopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!(m.opt_present("t")); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => { + panic!("test_reqopt failed (long arg)"); + } + } + let short_args = vec!["-t".to_string(), "20".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => { + panic!("test_reqopt failed (short arg)"); + } + } +} + +#[test] +fn test_reqopt_missing() { + let args = vec!["blah".to_string()]; + match Options::new() + .reqopt("t", "test", "testing", "TEST") + .parse(&args) + { + Err(OptionMissing(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_reqopt_no_arg() { + let long_args = vec!["--test".to_string()]; + let mut opts = Options::new(); + opts.reqopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } + let short_args = vec!["-t".to_string()]; + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_reqopt_multi() { + let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()]; + match Options::new() + .reqopt("t", "test", "testing", "TEST") + .parse(&args) + { + Err(OptionDuplicated(_)) => {} + _ => panic!(), + } +} + +// Tests for optopt +#[test] +fn test_optopt() { + let long_args = vec!["--test=20".to_string()]; + let mut opts = Options::new(); + opts.optopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!(), + } + let short_args = vec!["-t".to_string(), "20".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!(), + } +} + +#[test] +fn test_optopt_missing() { + let args = vec!["blah".to_string()]; + match Options::new() + .optopt("t", "test", "testing", "TEST") + .parse(&args) + { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!(), + } +} + +#[test] +fn test_optopt_no_arg() { + let long_args = vec!["--test".to_string()]; + let mut opts = Options::new(); + opts.optopt("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } + let short_args = vec!["-t".to_string()]; + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_optopt_multi() { + let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()]; + match Options::new() + .optopt("t", "test", "testing", "TEST") + .parse(&args) + { + Err(OptionDuplicated(_)) => {} + _ => panic!(), + } +} + +// Tests for optflag +#[test] +fn test_optflag() { + let long_args = vec!["--test".to_string()]; + let mut opts = Options::new(); + opts.optflag("t", "test", "testing"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!(), + } + let short_args = vec!["-t".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!(), + } +} + +#[test] +fn test_optflag_missing() { + let args = vec!["blah".to_string()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!(), + } +} + +#[test] +fn test_opt_end() { + let args = vec!["--".to_owned(), "-t".to_owned()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + assert_eq!(m.free.len(), 1); + assert_eq!(m.free[0], "-t"); + } + _ => panic!(), + } +} + +#[test] +fn test_opt_only_end() { + let args = vec!["--".to_owned()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + assert_eq!(m.free.len(), 0); + } + _ => panic!(), + } +} + +#[test] +fn test_optflag_long_arg() { + let args = vec!["--test=20".to_string()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Err(UnexpectedArgument(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_optflag_multi() { + let args = vec!["--test".to_string(), "-t".to_string()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Err(OptionDuplicated(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_optflag_short_arg() { + let args = vec!["-t".to_string(), "20".to_string()]; + match Options::new().optflag("t", "test", "testing").parse(&args) { + Ok(ref m) => { + // The next variable after the flag is just a free argument + + assert!(m.free[0] == "20"); + } + _ => panic!(), + } +} + +// Tests for optflagmulti +#[test] +fn test_optflagmulti_short1() { + let args = vec!["-v".to_string()]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 1); + } + _ => panic!(), + } +} + +#[test] +fn test_optflagmulti_short2a() { + let args = vec!["-v".to_string(), "-v".to_string()]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 2); + } + _ => panic!(), + } +} + +#[test] +fn test_optflagmulti_short2b() { + let args = vec!["-vv".to_string()]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("v"), 2); + } + _ => panic!(), + } +} + +#[test] +fn test_optflagmulti_long1() { + let args = vec!["--verbose".to_string()]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 1); + } + _ => panic!(), + } +} + +#[test] +fn test_optflagmulti_long2() { + let args = vec!["--verbose".to_string(), "--verbose".to_string()]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 2); + } + _ => panic!(), + } +} + +#[test] +fn test_optflagmulti_mix() { + let args = vec![ + "--verbose".to_string(), + "-v".to_string(), + "-vv".to_string(), + "verbose".to_string(), + ]; + match Options::new() + .optflagmulti("v", "verbose", "verbosity") + .parse(&args) + { + Ok(ref m) => { + assert_eq!(m.opt_count("verbose"), 4); + assert_eq!(m.opt_count("v"), 4); + } + _ => panic!(), + } +} + +// Tests for optflagopt +#[test] +fn test_optflagopt() { + let long_args = vec!["--test".to_string()]; + let mut opts = Options::new(); + opts.optflagopt("t", "test", "testing", "ARG"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!(), + } + let short_args = vec!["-t".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert!(m.opt_present("t")); + } + _ => panic!(), + } + let short_args = vec!["-t".to_string(), "x".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert_eq!(m.opt_str("t").unwrap(), "x"); + assert_eq!(m.opt_str("test").unwrap(), "x"); + } + _ => panic!(), + } + let long_args = vec!["--test=x".to_string()]; + match opts.parse(&long_args) { + Ok(ref m) => { + assert_eq!(m.opt_str("t").unwrap(), "x"); + assert_eq!(m.opt_str("test").unwrap(), "x"); + } + _ => panic!(), + } + let long_args = vec!["--test".to_string(), "x".to_string()]; + match opts.parse(&long_args) { + Ok(ref m) => { + assert_eq!(m.opt_str("t"), None); + assert_eq!(m.opt_str("test"), None); + } + _ => panic!(), + } + let no_args: Vec = vec![]; + match opts.parse(&no_args) { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!(), + } +} + +// Tests for optmulti +#[test] +fn test_optmulti() { + let long_args = vec!["--test=20".to_string()]; + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!(), + } + let short_args = vec!["-t".to_string(), "20".to_string()]; + match opts.parse(&short_args) { + Ok(ref m) => { + assert!((m.opt_present("test"))); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!((m.opt_present("t"))); + assert_eq!(m.opt_str("t").unwrap(), "20"); + } + _ => panic!(), + } +} + +#[test] +fn test_optmulti_missing() { + let args = vec!["blah".to_string()]; + match Options::new() + .optmulti("t", "test", "testing", "TEST") + .parse(&args) + { + Ok(ref m) => { + assert!(!m.opt_present("test")); + assert!(!m.opt_present("t")); + } + _ => panic!(), + } +} + +#[test] +fn test_optmulti_no_arg() { + let long_args = vec!["--test".to_string()]; + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } + let short_args = vec!["-t".to_string()]; + match opts.parse(&short_args) { + Err(ArgumentMissing(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_optmulti_multi() { + let args = vec!["--test=20".to_string(), "-t".to_string(), "30".to_string()]; + match Options::new() + .optmulti("t", "test", "testing", "TEST") + .parse(&args) + { + Ok(ref m) => { + assert!(m.opt_present("test")); + assert_eq!(m.opt_str("test").unwrap(), "20"); + assert!(m.opt_present("t")); + assert_eq!(m.opt_str("t").unwrap(), "20"); + let pair = m.opt_strs("test"); + assert!(pair[0] == "20"); + assert!(pair[1] == "30"); + } + _ => panic!(), + } +} + +#[test] +fn test_free_argument_is_hyphen() { + let args = vec!["-".to_string()]; + match Options::new().parse(&args) { + Ok(ref m) => { + assert_eq!(m.free.len(), 1); + assert_eq!(m.free[0], "-"); + } + _ => panic!(), + } +} + +#[test] +fn test_unrecognized_option() { + let long_args = vec!["--untest".to_string()]; + let mut opts = Options::new(); + opts.optmulti("t", "test", "testing", "TEST"); + match opts.parse(&long_args) { + Err(UnrecognizedOption(_)) => {} + _ => panic!(), + } + let short_args = vec!["-u".to_string()]; + match opts.parse(&short_args) { + Err(UnrecognizedOption(_)) => {} + _ => panic!(), + } +} + +#[test] +fn test_combined() { + let args = vec![ + "prog".to_string(), + "free1".to_string(), + "-s".to_string(), + "20".to_string(), + "free2".to_string(), + "--flag".to_string(), + "--long=30".to_string(), + "-f".to_string(), + "-m".to_string(), + "40".to_string(), + "-m".to_string(), + "50".to_string(), + "-n".to_string(), + "-A B".to_string(), + "-n".to_string(), + "-60 70".to_string(), + ]; + match Options::new() + .optopt("s", "something", "something", "SOMETHING") + .optflag("", "flag", "a flag") + .reqopt("", "long", "hi", "LONG") + .optflag("f", "", "another flag") + .optmulti("m", "", "mmmmmm", "YUM") + .optmulti("n", "", "nothing", "NOTHING") + .optopt("", "notpresent", "nothing to see here", "NOPE") + .parse(&args) + { + Ok(ref m) => { + assert!(m.free[0] == "prog"); + assert!(m.free[1] == "free1"); + assert_eq!(m.opt_str("s").unwrap(), "20"); + assert!(m.free[2] == "free2"); + assert!((m.opt_present("flag"))); + assert_eq!(m.opt_str("long").unwrap(), "30"); + assert!((m.opt_present("f"))); + let pair = m.opt_strs("m"); + assert!(pair[0] == "40"); + assert!(pair[1] == "50"); + let pair = m.opt_strs("n"); + assert!(pair[0] == "-A B"); + assert!(pair[1] == "-60 70"); + assert!((!m.opt_present("notpresent"))); + } + _ => panic!(), + } +} + +#[test] +fn test_mixed_stop() { + let args = vec![ + "-a".to_string(), + "b".to_string(), + "-c".to_string(), + "d".to_string(), + ]; + match Options::new() + .parsing_style(ParsingStyle::StopAtFirstFree) + .optflag("a", "", "") + .optopt("c", "", "", "") + .parse(&args) + { + Ok(ref m) => { + println!("{}", m.opt_present("c")); + assert!(m.opt_present("a")); + assert!(!m.opt_present("c")); + assert_eq!(m.free.len(), 3); + assert_eq!(m.free[0], "b"); + assert_eq!(m.free[1], "-c"); + assert_eq!(m.free[2], "d"); + } + _ => panic!(), + } +} + +#[test] +fn test_mixed_stop_hyphen() { + let args = vec![ + "-a".to_string(), + "-".to_string(), + "-c".to_string(), + "d".to_string(), + ]; + match Options::new() + .parsing_style(ParsingStyle::StopAtFirstFree) + .optflag("a", "", "") + .optopt("c", "", "", "") + .parse(&args) + { + Ok(ref m) => { + println!("{}", m.opt_present("c")); + assert!(m.opt_present("a")); + assert!(!m.opt_present("c")); + assert_eq!(m.free.len(), 3); + assert_eq!(m.free[0], "-"); + assert_eq!(m.free[1], "-c"); + assert_eq!(m.free[2], "d"); + } + _ => panic!(), + } +} + +#[test] +fn test_multi() { + let mut opts = Options::new(); + opts.optopt("e", "", "encrypt", "ENCRYPT"); + opts.optopt("", "encrypt", "encrypt", "ENCRYPT"); + opts.optopt("f", "", "flag", "FLAG"); + + let args_single = vec!["-e".to_string(), "foo".to_string()]; + let matches_single = &match opts.parse(&args_single) { + Ok(m) => m, + _ => panic!(), + }; + assert!(matches_single.opts_present(&["e".to_string()])); + assert!(matches_single.opts_present(&["encrypt".to_string(), "e".to_string()])); + assert!(matches_single.opts_present(&["e".to_string(), "encrypt".to_string()])); + assert!(!matches_single.opts_present(&["encrypt".to_string()])); + assert!(!matches_single.opts_present(&["thing".to_string()])); + assert!(!matches_single.opts_present(&[])); + + assert_eq!(matches_single.opts_str(&["e".to_string()]).unwrap(), "foo"); + assert_eq!( + matches_single + .opts_str(&["e".to_string(), "encrypt".to_string()]) + .unwrap(), + "foo" + ); + assert_eq!( + matches_single + .opts_str(&["encrypt".to_string(), "e".to_string()]) + .unwrap(), + "foo" + ); + + let args_both = vec![ + "-e".to_string(), + "foo".to_string(), + "--encrypt".to_string(), + "foo".to_string(), + ]; + let matches_both = &match opts.parse(&args_both) { + Ok(m) => m, + _ => panic!(), + }; + assert!(matches_both.opts_present(&["e".to_string()])); + assert!(matches_both.opts_present(&["encrypt".to_string()])); + assert!(matches_both.opts_present(&["encrypt".to_string(), "e".to_string()])); + assert!(matches_both.opts_present(&["e".to_string(), "encrypt".to_string()])); + assert!(!matches_both.opts_present(&["f".to_string()])); + assert!(!matches_both.opts_present(&["thing".to_string()])); + assert!(!matches_both.opts_present(&[])); + + assert_eq!(matches_both.opts_str(&["e".to_string()]).unwrap(), "foo"); + assert_eq!( + matches_both.opts_str(&["encrypt".to_string()]).unwrap(), + "foo" + ); + assert_eq!( + matches_both + .opts_str(&["e".to_string(), "encrypt".to_string()]) + .unwrap(), + "foo" + ); + assert_eq!( + matches_both + .opts_str(&["encrypt".to_string(), "e".to_string()]) + .unwrap(), + "foo" + ); +} + +#[test] +fn test_nospace() { + let args = vec!["-Lfoo".to_string(), "-M.".to_string()]; + let matches = &match Options::new() + .optmulti("L", "", "library directory", "LIB") + .optmulti("M", "", "something", "MMMM") + .parse(&args) + { + Ok(m) => m, + _ => panic!(), + }; + assert!(matches.opts_present(&["L".to_string()])); + assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo"); + assert!(matches.opts_present(&["M".to_string()])); + assert_eq!(matches.opts_str(&["M".to_string()]).unwrap(), "."); +} + +#[test] +fn test_nospace_conflict() { + let args = vec!["-vvLverbose".to_string(), "-v".to_string()]; + let matches = &match Options::new() + .optmulti("L", "", "library directory", "LIB") + .optflagmulti("v", "verbose", "Verbose") + .parse(&args) + { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert!(matches.opts_present(&["L".to_string()])); + assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose"); + assert!(matches.opts_present(&["v".to_string()])); + assert_eq!(3, matches.opt_count("v")); +} + +#[test] +fn test_long_to_short() { + let mut short = Opt { + name: Name::Long("banana".to_string()), + hasarg: HasArg::Yes, + occur: Occur::Req, + aliases: Vec::new(), + }; + short.aliases = vec![Opt { + name: Name::Short('b'), + hasarg: HasArg::Yes, + occur: Occur::Req, + aliases: Vec::new(), + }]; + let mut opts = Options::new(); + opts.reqopt("b", "banana", "some bananas", "VAL"); + let verbose = &opts.grps[0]; + assert!(verbose.long_to_short() == short); +} + +#[test] +fn test_aliases_long_and_short() { + let args = vec!["-a".to_string(), "--apple".to_string(), "-a".to_string()]; + + let matches = Options::new() + .optflagmulti("a", "apple", "Desc") + .parse(&args) + .unwrap(); + assert_eq!(3, matches.opt_count("a")); + assert_eq!(3, matches.opt_count("apple")); +} + +#[test] +fn test_usage() { + let mut opts = Options::new(); + opts.reqopt("b", "banana", "Desc", "VAL"); + opts.optopt("a", "012345678901234567890123456789", "Desc", "VAL"); + opts.optflag("k", "kiwi", "Desc"); + opts.optflagopt("p", "", "Desc", "VAL"); + opts.optmulti("l", "", "Desc", "VAL"); + opts.optflag("", "starfruit", "Starfruit"); + + let expected = "Usage: fruits + +Options: + -b, --banana VAL Desc + -a, --012345678901234567890123456789 VAL + Desc + -k, --kiwi Desc + -p [VAL] Desc + -l VAL Desc + --starfruit Starfruit +"; + + let generated_usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", generated_usage); + assert_eq!(generated_usage, expected); +} + +#[test] +fn test_usage_description_wrapping() { + // indentation should be 24 spaces + // lines wrap after 78: or rather descriptions wrap after 54 + + let mut opts = Options::new(); + opts.optflag( + "k", + "kiwi", + "This is a long description which won't be wrapped..+..", + ); // 54 + opts.optflag( + "a", + "apple", + "This is a long description which _will_ be wrapped..+..", + ); + opts.optflag( + "b", + "banana", + "HereWeNeedOneSingleWordThatIsLongerThanTheWrappingLengthAndThisIsIt", + ); + + let expected = "Usage: fruits + +Options: + -k, --kiwi This is a long description which won't be wrapped..+.. + -a, --apple This is a long description which _will_ be + wrapped..+.. + -b, --banana HereWeNeedOneSingleWordThatIsLongerThanTheWrappingLengthAndThisIsIt +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_usage_description_multibyte_handling() { + let mut opts = Options::new(); + opts.optflag( + "k", + "k\u{2013}w\u{2013}", + "The word kiwi is normally spelled with two i's", + ); + opts.optflag( + "a", + "apple", + "This \u{201C}description\u{201D} has some characters that could \ + confuse the line wrapping; an apple costs 0.51€ in some parts of Europe.", + ); + + let expected = "Usage: fruits + +Options: + -k, --k–w– The word kiwi is normally spelled with two i's + -a, --apple This “description” has some characters that could + confuse the line wrapping; an apple costs 0.51€ in + some parts of Europe. +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_usage_description_newline_handling() { + let mut opts = Options::new(); + opts.optflag( + "k", + "k\u{2013}w\u{2013}", + "The word kiwi is normally spelled with two i's", + ); + opts.optflag( + "a", + "apple", + "This description forces a new line.\n Here is a premature\n\ + newline", + ); + + let expected = "Usage: fruits + +Options: + -k, --k–w– The word kiwi is normally spelled with two i's + -a, --apple This description forces a new line. + Here is a premature + newline +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_usage_multiwidth() { + let mut opts = Options::new(); + opts.optflag("a", "apple", "apple description"); + opts.optflag("b", "banana\u{00AB}", "banana description"); + opts.optflag("c", "brûlée", "brûlée quite long description"); + opts.optflag("k", "kiwi\u{20AC}", "kiwi description"); + opts.optflag("o", "orange\u{2039}", "orange description"); + opts.optflag( + "r", + "raspberry-but-making-this-option-way-too-long", + "raspberry description is also quite long indeed longer than \ + every other piece of text we might encounter here and thus will \ + be automatically broken up", + ); + + let expected = "Usage: fruits + +Options: + -a, --apple apple description + -b, --banana« banana description + -c, --brûlée brûlée quite long description + -k, --kiwi€ kiwi description + -o, --orange‹ orange description + -r, --raspberry-but-making-this-option-way-too-long\u{0020} + raspberry description is also quite long indeed longer + than every other piece of text we might encounter here + and thus will be automatically broken up +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_usage_short_only() { + let mut opts = Options::new(); + opts.optopt("k", "", "Kiwi", "VAL"); + opts.optflag("s", "", "Starfruit"); + opts.optflagopt("a", "", "Apple", "TYPE"); + + let expected = "Usage: fruits + +Options: + -k VAL Kiwi + -s Starfruit + -a [TYPE] Apple +"; + + let usage = opts.usage("Usage: fruits"); + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_usage_long_only() { + let mut opts = Options::new(); + opts.optopt("", "kiwi", "Kiwi", "VAL"); + opts.optflag("", "starfruit", "Starfruit"); + opts.optflagopt("", "apple", "Apple", "TYPE"); + + let expected = "Usage: fruits + +Options: + --kiwi VAL Kiwi + --starfruit Starfruit + --apple [TYPE] Apple +"; + + let usage = opts.usage("Usage: fruits"); + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_short_usage() { + let mut opts = Options::new(); + opts.reqopt("b", "banana", "Desc", "VAL"); + opts.optopt("a", "012345678901234567890123456789", "Desc", "VAL"); + opts.optflag("k", "kiwi", "Desc"); + opts.optflagopt("p", "", "Desc", "VAL"); + opts.optmulti("l", "", "Desc", "VAL"); + + let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_string(); + let generated_usage = opts.short_usage("fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", generated_usage); + assert_eq!(generated_usage, expected); +} +#[test] +fn test_nonexistant_opt() { + let mut opts = Options::new(); + opts.optflag("b", "bar", "Desc"); + let args: Vec = Vec::new(); + let matches = opts.parse(&args).unwrap(); + assert_eq!(matches.opt_defined("foo"), false); + assert_eq!(matches.opt_defined("bar"), true); +} +#[test] +fn test_args_with_equals() { + let mut opts = Options::new(); + opts.optopt("o", "one", "One", "INFO"); + opts.optopt("t", "two", "Two", "INFO"); + + let args = vec![ + "--one".to_string(), + "A=B".to_string(), + "--two=C=D".to_string(), + ]; + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert_eq!(matches.opts_str(&["o".to_string()]).unwrap(), "A=B"); + assert_eq!(matches.opts_str(&["t".to_string()]).unwrap(), "C=D"); +} + +#[test] +fn test_long_only_usage() { + let mut opts = Options::new(); + opts.long_only(true); + opts.optflag("k", "kiwi", "Description"); + opts.optflag("a", "apple", "Description"); + + let expected = "Usage: fruits + +Options: + -k, -kiwi Description + -a, -apple Description +"; + + let usage = opts.usage("Usage: fruits"); + + debug!("expected: <<{}>>", expected); + debug!("generated: <<{}>>", usage); + assert!(usage == expected) +} + +#[test] +fn test_long_only_mode() { + let mut opts = Options::new(); + opts.long_only(true); + opts.optopt("a", "apple", "Description", "X"); + opts.optopt("b", "banana", "Description", "X"); + opts.optopt("c", "currant", "Description", "X"); + opts.optopt("", "durian", "Description", "X"); + opts.optopt("e", "", "Description", "X"); + opts.optopt("", "fruit", "Description", "X"); + + let args = vec![ + "-a", + "A", + "-b=B", + "--c=C", + "-durian", + "D", + "--e", + "E", + "-fruit=any", + ]; + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert_eq!(matches.opts_str(&["a".to_string()]).unwrap(), "A"); + assert_eq!(matches.opts_str(&["b".to_string()]).unwrap(), "B"); + assert_eq!(matches.opts_str(&["c".to_string()]).unwrap(), "C"); + assert_eq!(matches.opts_str(&["durian".to_string()]).unwrap(), "D"); + assert_eq!(matches.opts_str(&["e".to_string()]).unwrap(), "E"); + assert_eq!(matches.opts_str(&["fruit".to_string()]).unwrap(), "any"); +} + +#[test] +fn test_long_only_mode_no_short_parse() { + let mut opts = Options::new(); + opts.long_only(true); + opts.optflag("h", "help", "Description"); + opts.optflag("i", "ignore", "Description"); + opts.optflag("", "hi", "Description"); + + let args = vec!["-hi"]; + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert!(matches.opt_present("hi")); + assert!(!matches.opt_present("h")); + assert!(!matches.opt_present("i")); +} + +#[test] +fn test_normal_mode_no_long_parse() { + // Like test_long_only_mode_no_short_parse, but we make sure + // that long_only can be disabled, and the right thing + // happens. + let mut opts = Options::new(); + opts.long_only(true); + opts.optflag("h", "help", "Description"); + opts.optflag("i", "ignore", "Description"); + opts.optflag("", "hi", "Description"); + opts.long_only(false); + + let args = vec!["-hi"]; + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert!(!matches.opt_present("hi")); + assert!(matches.opt_present("h")); + assert!(matches.opt_present("i")); +} + +#[test] +#[should_panic] +fn test_long_name_too_short() { + let mut opts = Options::new(); + opts.optflag("", "a", "Oops, long option too short"); +} + +#[test] +#[should_panic] +fn test_undefined_opt_present() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + let args = vec!["-h"]; + match opts.parse(args) { + Ok(matches) => assert!(!matches.opt_present("undefined")), + Err(e) => panic!("{}", e), + } +} + +#[test] +fn test_opt_default() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflag("i", "ignore", "Description"); + opts.optflag("r", "run", "Description"); + opts.long_only(false); + + let args: Vec = ["-i", "-r", "10"].iter().map(|x| x.to_string()).collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + assert_eq!(matches.opt_default("help", ""), None); + assert_eq!(matches.opt_default("i", "def"), Some("def".to_string())); +} + +#[test] +fn test_opt_get() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflagopt("i", "ignore", "Description", "true | false"); + opts.optflagopt("r", "run", "Description", "0 .. 10"); + opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0"); + opts.long_only(false); + + let args: Vec = ["-i", "true", "-p", "1.1"] + .iter() + .map(|x| x.to_string()) + .collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + let h_arg = matches.opt_get::("help"); + assert_eq!(h_arg, Ok(None)); + let i_arg = matches.opt_get("i"); + assert_eq!(i_arg, Ok(Some(true))); + let p_arg = matches.opt_get("p"); + assert_eq!(p_arg, Ok(Some(1.1))); +} + +#[test] +fn test_opt_get_default() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflagopt("i", "ignore", "Description", "true | false"); + opts.optflagopt("r", "run", "Description", "0 .. 10"); + opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0"); + opts.long_only(false); + + let args: Vec = ["-i", "true", "-p", "1.1"] + .iter() + .map(|x| x.to_string()) + .collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + let h_arg = matches.opt_get_default("help", 10); + assert_eq!(h_arg, Ok(10)); + let i_arg = matches.opt_get_default("i", false); + assert_eq!(i_arg, Ok(true)); + let p_arg = matches.opt_get_default("p", 10.2); + assert_eq!(p_arg, Ok(1.1)); +} + +#[test] +fn test_opt_positions() { + let mut opts = Options::new(); + opts.optflagmulti("a", "act", "Description"); + opts.optflagmulti("e", "enact", "Description"); + opts.optflagmulti("r", "react", "Description"); + + let args: Vec = ["-a", "-a", "-r", "-a", "-r", "-r"] + .iter() + .map(|x| x.to_string()) + .collect(); + + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + + let a_pos = matches.opt_positions("a"); + assert_eq!(a_pos, vec![0, 1, 3]); + let e_pos = matches.opt_positions("e"); + assert_eq!(e_pos, vec![]); + let r_pos = matches.opt_positions("r"); + assert_eq!(r_pos, vec![2, 4, 5]); +} + +#[test] +fn test_opt_strs_pos() { + let mut opts = Options::new(); + opts.optmulti("a", "act", "Description", "NUM"); + opts.optmulti("e", "enact", "Description", "NUM"); + opts.optmulti("r", "react", "Description", "NUM"); + + let args: Vec = ["-a1", "-a2", "-r3", "-a4", "-r5", "-r6"] + .iter() + .map(|x| x.to_string()) + .collect(); + + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e), + }; + + let a_pos = matches.opt_strs_pos("a"); + assert_eq!( + a_pos, + vec![ + (0, "1".to_string()), + (1, "2".to_string()), + (3, "4".to_string()) + ] + ); + let e_pos = matches.opt_strs_pos("e"); + assert_eq!(e_pos, vec![]); + let r_pos = matches.opt_strs_pos("r"); + assert_eq!( + r_pos, + vec![ + (2, "3".to_string()), + (4, "5".to_string()), + (5, "6".to_string()) + ] + ); +} -- cgit v1.2.3