1 use std::collections::HashMap;
2 
3 use serde::Deserialize;
4 
5 use crate::{Docopt, ArgvMap, Error};
6 use crate::Value::{self, Switch, Plain};
7 
get_args(doc: &str, argv: &[&'static str]) -> ArgvMap8 fn get_args(doc: &str, argv: &[&'static str]) -> ArgvMap {
9     let dopt = match Docopt::new(doc) {
10         Err(err) => panic!("Invalid usage: {}", err),
11         Ok(dopt) => dopt,
12     };
13     match dopt.argv(vec!["cmd"].iter().chain(argv.iter())).parse() {
14         Err(err) => panic!("{}", err),
15         Ok(vals) => vals,
16     }
17 }
18 
map_from_alist(alist: Vec<(&'static str, Value)>) -> HashMap<String, Value>19 fn map_from_alist(alist: Vec<(&'static str, Value)>)
20                  -> HashMap<String, Value> {
21     alist.into_iter().map(|(k, v)| (k.to_string(), v)).collect()
22 }
23 
same_args(expected: &HashMap<String, Value>, got: &ArgvMap)24 fn same_args(expected: &HashMap<String, Value>, got: &ArgvMap) {
25     for (k, ve) in expected.iter() {
26         match got.map.find(k) {
27             None => panic!("EXPECTED has '{}' but GOT does not.", k),
28             Some(vg) => {
29                 assert!(ve == vg,
30                         "{}: EXPECTED = '{:?}' != '{:?}' = GOT", k, ve, vg)
31             }
32         }
33     }
34     for (k, vg) in got.map.iter() {
35         match got.map.find(k) {
36             None => panic!("GOT has '{}' but EXPECTED does not.", k),
37             Some(ve) => {
38                 assert!(vg == ve,
39                         "{}: GOT = '{:?}' != '{:?}' = EXPECTED", k, vg, ve)
40             }
41         }
42     }
43 }
44 
45 macro_rules! test_expect(
46     ($name:ident, $doc:expr, $args:expr, $expected:expr) => (
47         #[test]
48         fn $name() {
49             let vals = get_args($doc, $args);
50             let expected = map_from_alist($expected);
51             same_args(&expected, &vals);
52         }
53     );
54 );
55 
56 macro_rules! test_user_error(
57     ($name:ident, $doc:expr, $args:expr) => (
58         #[test]
59         #[should_panic]
60         fn $name() { get_args($doc, $args); }
61     );
62 );
63 
64 test_expect!(test_issue_13, "Usage: prog file <file>", &["file", "file"],
65              vec![("file", Switch(true)),
66                   ("<file>", Plain(Some("file".to_string())))]);
67 
68 test_expect!(test_issue_129, "Usage: prog [options]
69 
70 Options:
71     --foo ARG   Foo foo.",
72              &["--foo=a b"],
73              vec![("--foo", Plain(Some("a b".into())))]);
74 
75 #[test]
regression_issue_12()76 fn regression_issue_12() {
77     const USAGE: &'static str = "
78     Usage:
79         whisper info <file>
80         whisper update <file> <timestamp> <value>
81         whisper mark <file> <value>
82     ";
83 
84     #[derive(Deserialize, Debug)]
85     struct Args {
86         arg_file: String,
87         cmd_info: bool,
88         cmd_update: bool,
89         arg_timestamp: u64,
90         arg_value: f64,
91     }
92 
93     let dopt: Args = Docopt::new(USAGE)
94         .unwrap()
95         .argv(&["whisper", "mark", "./p/blah", "100"])
96         .deserialize()
97         .unwrap();
98     assert_eq!(dopt.arg_timestamp, 0);
99 }
100 
101 #[test]
regression_issue_195()102 fn regression_issue_195() {
103     const USAGE: &'static str = "
104     Usage:
105         slow [-abcdefghijklmnopqrs...]
106     ";
107 
108     let argv = &["slow", "-abcdefghijklmnopqrs"];
109     let dopt : Docopt = Docopt::new(USAGE).unwrap().argv(argv);
110 
111     dopt.parse().unwrap();
112 }
113 
114 #[test]
regression_issue_219()115 fn regression_issue_219() {
116     #[derive(Deserialize)]
117     struct Args {
118         arg_type: Vec<String>,
119         arg_param: Vec<String>,
120     }
121 
122     const USAGE: &'static str = "
123     Usage:
124         encode [-v <type> <param>]...
125     ";
126 
127     let argv = &["encode", "-v", "bool", "true", "string", "foo"];
128     let args: Args = Docopt::new(USAGE).unwrap().argv(argv).deserialize().unwrap();
129     assert_eq!(args.arg_type, vec!["bool".to_owned(), "string".to_owned()]);
130     assert_eq!(args.arg_param, vec!["true".to_owned(), "foo".to_owned()]);
131 }
132 
133 #[test]
test_unit_struct()134 fn test_unit_struct() {
135     const USAGE: &'static str = "
136     Usage:
137         cargo version [options]
138 
139     Options:
140         -h, --help               Print this message
141     ";
142 
143     #[derive(Deserialize)]
144     struct Options;
145 
146     let argv = &["cargo", "version"];
147     let dopt: Result<Options, Error>= Docopt::new(USAGE)
148         .unwrap()
149         .argv(argv)
150         .deserialize();
151     assert!(dopt.is_ok());
152 }
153 
154 mod testcases;
155 mod suggestions;
156