summaryrefslogtreecommitdiffstats
path: root/vendor/getopts/src/tests/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/getopts/src/tests/mod.rs')
-rw-r--r--vendor/getopts/src/tests/mod.rs1254
1 files changed, 1254 insertions, 0 deletions
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<String> = 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<String> = 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<String> = ["-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<String> = ["-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::<i32>("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<String> = ["-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<String> = ["-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<String> = ["-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())
+ ]
+ );
+}