Last active
June 7, 2017 15:10
-
-
Save ExpHP/bfb5a2cc0a0a170e4d864f9694304dde to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #[cfg(test)] | |
| mod test_parsing { | |
| // NOTES: | |
| // OptionStore holds the defined options for a program. | |
| // The function being tested canonicalizes arguments like getopt. | |
| // | |
| // .add_short() and .add_long() take a "number of option arguments" argument, (e.g. Precisely(2)) | |
| // because I mistakenly thought that options were allowed to take more than one. | |
| // YOU CAN IGNORE ANY TEST WHERE THE INPUT SUPPLIES AN OPTION THAT TAKES MULTIPLE ARGUMENTS | |
| // | |
| // IIRC abbreviations for long options are not tested because the feature | |
| // is dumb and so I didn't implement it. | |
| #[test] | |
| fn no_input() { | |
| let store = OptionStore::new(); | |
| check!(&store, [], []); | |
| } | |
| #[test] | |
| fn unusual_positionals() { | |
| let mut store = OptionStore::new(); | |
| store.add_short('a', Precisely(0)); | |
| store.add_long("foo", Precisely(0)); | |
| for s in vec![ | |
| "", "-", // special cases | |
| " -a", " -q", " --foo", " --bar", // space before option | |
| ] { | |
| check!(&store, ["a", s, "b"], [pos("a"), pos(s), pos("b")]); | |
| } | |
| } | |
| #[test] | |
| fn short_options() { | |
| let mut store = OptionStore::new(); | |
| for c in "abcd".chars() { | |
| store.add_short(c, Precisely(0)); | |
| } | |
| store.add_short('X', Precisely(1)); | |
| store.add_short('Y', Precisely(2)); | |
| store.add_short('o', Optional); | |
| // a short | |
| check!(&store, ["-a"], [short('a')]); | |
| check!(&store, ["-q"], unknown_short('q')); | |
| // many shorts | |
| check!(&store, ["-abcd"], [short('a'), short('b'), short('c'), short('d')]); | |
| check!(&store, ["-abqd"], unknown_short('q')); | |
| // shorts with arguments | |
| check!(&store, ["-aX", "cq"], [short('a'), short('X', "cq")]); | |
| check!(&store, ["-aXcq"], [short('a'), short('X', "cq")]); | |
| check!(&store, ["-aY", "cq", "a"], [short('a'), short('Y', "cq", "a")]); | |
| check!(&store, ["-aYcq", "a"], [short('a'), short('Y', "cq", "a")]); | |
| // argument errors | |
| check!(&store, ["-aX"], missing_arg_short(&store, 'X', 0)); | |
| check!(&store, ["-aY"], missing_arg_short(&store, 'Y', 0)); | |
| check!(&store, ["-aY", "cq"], missing_arg_short(&store, 'Y', 1)); | |
| check!(&store, ["-aYcq"], missing_arg_short(&store, 'Y', 1)); | |
| // optional arguments | |
| check!(&store, ["-o"], [short('o', "")]); | |
| check!(&store, ["-o", "-a"], [short('o', ""), short('a')]); | |
| check!(&store, ["-oa"], [short('o', "a")]); | |
| // interpretation of = sign (or rather, the lack thereof) | |
| check!(&store, ["-X=cd"], [short('X', "=cd")]); | |
| // argument which resembles an option | |
| check!(&store, ["-X", "-q"], [short('X', "-q")]); // no "unknown option" | |
| check!(&store, ["-X", "-X"], [short('X', "-X")]); // no "missing arg" | |
| // empty argument | |
| check!(&store, ["-X", ""], [short('X', "")]); | |
| // don't eat too many args | |
| check!(&store, ["-a", "a"], [short('a'), pos("a")]); | |
| check!(&store, ["-Y", "a", "b", "c"], [short('Y', "a", "b"), pos("c")]); | |
| } | |
| #[test] | |
| fn long_options() { | |
| let mut store = OptionStore::new(); | |
| store.add_long("foo", Precisely(0)); | |
| store.add_long("no-bar", Precisely(0)); // something with a hyphen | |
| store.add_long("one", Precisely(1)); | |
| store.add_long("two", Precisely(2)); | |
| store.add_long("opt", Optional); | |
| // a long | |
| check!(&store, ["--foo"], [long("foo")]); | |
| check!(&store, ["--no-bar"], [long("no-bar")]); | |
| check!(&store, ["--derp"], unknown_long("derp")); | |
| // longs with arguments | |
| check!(&store, ["--one=arg"], [long("one", "arg")]); | |
| check!(&store, ["--one", "arg"], [long("one", "arg")]); | |
| check!(&store, ["--two=arg", "yar"], [long("two", "arg", "yar")]); | |
| check!(&store, ["--two", "arg", "yar"], [long("two", "arg", "yar")]); | |
| // argument errors | |
| check!(&store, ["--foo=a"], unexpected_arg_long(&store, "foo")); | |
| check!(&store, ["--foo="], unexpected_arg_long(&store, "foo")); | |
| check!(&store, ["--one"], missing_arg_long(&store, "one", 0)); | |
| check!(&store, ["--two"], missing_arg_long(&store, "two", 0)); | |
| check!(&store, ["--two", "a"], missing_arg_long(&store, "two", 1)); | |
| check!(&store, ["--two=a"], missing_arg_long(&store, "two", 1)); | |
| // optional arguments | |
| check!(&store, ["--opt=a"], [long("opt", "a")]); | |
| check!(&store, ["--opt", "a"], [long("opt", ""), pos("a")]); | |
| check!(&store, ["--opt="], [long("opt", "")]); | |
| check!(&store, ["--opt"], [long("opt", "")]); | |
| // argument containing literal '=' | |
| check!(&store, ["--one", "a=b"], [long("one", "a=b")]); | |
| check!(&store, ["--one=a=b"], [long("one", "a=b")]); | |
| // argument which resembles an option | |
| check!(&store, ["--one", "--derp"], [long("one", "--derp")]); // no "unknown option" | |
| check!(&store, ["--one", "--one"], [long("one", "--one")]); // no "missing arg" | |
| // empty argument | |
| check!(&store, ["--one", ""], [long("one", "")]); | |
| check!(&store, ["--one="], [long("one", "")]); | |
| // don't eat too many args | |
| check!(&store, ["--foo", "a"], [long("foo"), pos("a")]); | |
| check!(&store, ["--two", "a", "b", "c"], [long("two", "a", "b"), pos("c")]); | |
| } | |
| #[test] | |
| fn test_double_dashes() { | |
| let mut store = OptionStore::new(); | |
| store.add_short('X', Precisely(1)); | |
| store.add_long("one", Precisely(1)); | |
| // everything after a double dash is a positional arg... | |
| check!(&store, ["--", "--", "--"], [dd(), pos("--"), pos("--")]); | |
| check!(&store, ["--", "-X3", "--one=3"], [dd(), pos("-X3"), pos("--one=3")]); | |
| check!(&store, ["--", "-q"], [dd(), pos("-q")]); // no "unknown option" | |
| check!(&store, ["--", "--bar"], [dd(), pos("--bar")]); | |
| check!(&store, ["--", "-X"], [dd(), pos("-X")]); // no "missing option arg" | |
| check!(&store, ["--", "--one"], [dd(), pos("--one")]); | |
| // double dash can be interpreted as an option argument instead, in which case the above | |
| // no longer applies. Fiendish! | |
| check!(&store, ["-X", "--", "--", "--"], [short('X', "--"), dd(), pos("--")]); | |
| check!(&store, ["-X", "--", "-X3", "--one=3"], [short('X', "--"), short('X', "3"), long("one", "3")]); | |
| check!(&store, ["-X", "--", "-q"], unknown_short('q')); | |
| check!(&store, ["-X", "--", "--bar"], unknown_long("bar")); | |
| check!(&store, ["-X", "--", "-X"], missing_arg_short(&store, 'X', 0)); | |
| check!(&store, ["-X", "--", "--one"], missing_arg_long(&store, "one", 0)); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment