1 use std::str::FromStr;
2 use std::ffi::OsString;
3 
4 use pico_args::*;
5 
to_vec(args: &[&str]) -> Vec<OsString>6 fn to_vec(args: &[&str]) -> Vec<OsString> {
7     args.iter().map(|s| s.to_string().into()).collect()
8 }
9 
10 #[test]
no_args()11 fn no_args() {
12     let _ = Arguments::from_vec(to_vec(&[]));
13 }
14 
15 #[test]
single_short_contains()16 fn single_short_contains() {
17     let mut args = Arguments::from_vec(to_vec(&["-V"]));
18     assert!(args.contains("-V"));
19 }
20 
21 #[test]
single_long_contains()22 fn single_long_contains() {
23     let mut args = Arguments::from_vec(to_vec(&["--version"]));
24     assert!(args.contains("--version"));
25 }
26 
27 #[test]
contains_two_01()28 fn contains_two_01() {
29     let mut args = Arguments::from_vec(to_vec(&["--version"]));
30     assert!(args.contains(["-v", "--version"]));
31 }
32 
33 #[test]
contains_two_02()34 fn contains_two_02() {
35     let mut args = Arguments::from_vec(to_vec(&["-v"]));
36     assert!(args.contains(["-v", "--version"]));
37 }
38 
39 #[test]
contains_two_03()40 fn contains_two_03() {
41     let mut args = Arguments::from_vec(to_vec(&["-v", "--version"]));
42     assert!(args.contains(["-v", "--version"]));
43 }
44 
45 #[test]
46 #[should_panic]
invalid_flag_01()47 fn invalid_flag_01() {
48     let mut args = Arguments::from_vec(to_vec(&["-v", "--version"]));
49     assert!(args.contains("v"));
50 }
51 
52 #[cfg(debug_assertions)]
53 #[test]
54 #[should_panic]
invalid_flag_02()55 fn invalid_flag_02() {
56     let mut args = Arguments::from_vec(to_vec(&["-v", "--version"]));
57     assert!(args.contains(["v", "--version"]));
58 }
59 
60 #[cfg(debug_assertions)]
61 #[test]
62 #[should_panic]
invalid_flag_03()63 fn invalid_flag_03() {
64     let mut args = Arguments::from_vec(to_vec(&["-v", "--version"]));
65     assert!(args.contains(["-v", "-version"]));
66 }
67 
68 #[cfg(debug_assertions)]
69 #[test]
70 #[should_panic]
invalid_flag_04()71 fn invalid_flag_04() {
72     let mut args = Arguments::from_vec(to_vec(&["-v", "--version"]));
73     assert!(args.contains(["-v", "version"]));
74 }
75 
76 
77 #[test]
option_01()78 fn option_01() {
79     let mut args = Arguments::from_vec(to_vec(&["-w", "10"]));
80     let value: Option<u32> = args.opt_value_from_str("-w").unwrap();
81     assert_eq!(value.unwrap(), 10);
82 }
83 
84 #[test]
option_02()85 fn option_02() {
86     let mut args = Arguments::from_vec(to_vec(&["--width", "10"]));
87     let value: Option<u32> = args.opt_value_from_str("--width").unwrap();
88     assert_eq!(value.unwrap(), 10);
89 }
90 
91 #[test]
option_03()92 fn option_03() {
93     let mut args = Arguments::from_vec(to_vec(&["--name", "test"]));
94     let value: Option<String> = args.opt_value_from_str("--name").unwrap();
95     assert_eq!(value.unwrap(), "test");
96 }
97 
98 #[cfg(feature = "eq-separator")]
99 #[test]
eq_option_01()100 fn eq_option_01() {
101     let mut args = Arguments::from_vec(to_vec(&["-w=10"]));
102     let value: Option<u32> = args.opt_value_from_str("-w").unwrap();
103     assert_eq!(value.unwrap(), 10);
104 }
105 
106 #[cfg(feature = "eq-separator")]
107 #[test]
eq_option_02()108 fn eq_option_02() {
109     let mut args = Arguments::from_vec(to_vec(&["-w='10'"]));
110     let value: Option<u32> = args.opt_value_from_str("-w").unwrap();
111     assert_eq!(value.unwrap(), 10);
112 }
113 
114 #[cfg(feature = "eq-separator")]
115 #[test]
eq_option_03()116 fn eq_option_03() {
117     let mut args = Arguments::from_vec(to_vec(&["-w=\"10\""]));
118     let value: Option<u32> = args.opt_value_from_str("-w").unwrap();
119     assert_eq!(value.unwrap(), 10);
120 }
121 
122 #[cfg(feature = "eq-separator")]
123 #[test]
eq_option_04()124 fn eq_option_04() {
125     let mut args = Arguments::from_vec(to_vec(&["--width2=15", "--width=10"]));
126     let value: Option<u32> = args.opt_value_from_str("--width").unwrap();
127     assert_eq!(value.unwrap(), 10);
128 }
129 
130 #[cfg(feature = "eq-separator")]
131 #[test]
eq_option_err_01()132 fn eq_option_err_01() {
133     let mut args = Arguments::from_vec(to_vec(&["-w="]));
134     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
135     assert_eq!(value.unwrap_err().to_string(),
136                "the '-w' option doesn't have an associated value");
137 }
138 
139 #[cfg(feature = "eq-separator")]
140 #[test]
eq_option_err_02()141 fn eq_option_err_02() {
142     let mut args = Arguments::from_vec(to_vec(&["-w='"]));
143     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
144     assert_eq!(value.unwrap_err().to_string(),
145                "the '-w' option doesn't have an associated value");
146 }
147 
148 #[cfg(feature = "eq-separator")]
149 #[test]
eq_option_err_03()150 fn eq_option_err_03() {
151     let mut args = Arguments::from_vec(to_vec(&["-w=''"]));
152     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
153     assert_eq!(value.unwrap_err().to_string(),
154                "the '-w' option doesn't have an associated value");
155 }
156 
157 #[cfg(feature = "eq-separator")]
158 #[test]
eq_option_err_04()159 fn eq_option_err_04() {
160     let mut args = Arguments::from_vec(to_vec(&["-w='\""]));
161     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
162     assert_eq!(value.unwrap_err().to_string(),
163                "the '-w' option doesn't have an associated value");
164 }
165 
166 #[cfg(feature = "eq-separator")]
167 #[test]
eq_option_err_05()168 fn eq_option_err_05() {
169     let mut args = Arguments::from_vec(to_vec(&["-w='10\""]));
170     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
171     assert_eq!(value.unwrap_err().to_string(),
172                "the '-w' option doesn't have an associated value");
173 }
174 
175 #[cfg(feature = "eq-separator")]
176 #[test]
eq_option_err_06()177 fn eq_option_err_06() {
178     let mut args = Arguments::from_vec(to_vec(&["-w-10"]));
179     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
180     assert_eq!(value.unwrap(), None);
181 }
182 
183 #[cfg(feature = "eq-separator")]
184 #[test]
eq_option_err_07()185 fn eq_option_err_07() {
186     let mut args = Arguments::from_vec(to_vec(&["-w=a"]));
187     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
188     assert_eq!(value.unwrap_err().to_string(),
189                "failed to parse 'a' cause invalid digit found in string");
190 }
191 
192 #[cfg(not(feature = "eq-separator"))]
193 #[test]
no_eq_separator_01()194 fn no_eq_separator_01() {
195     let mut args = Arguments::from_vec(to_vec(&["-w=a"]));
196     let value: Result<Option<u32>, Error> = args.opt_value_from_str("-w");
197     assert_eq!(value.unwrap(), None);
198 }
199 
200 #[test]
duplicated_options_01()201 fn duplicated_options_01() {
202     let mut args = Arguments::from_vec(to_vec(&["--name", "test1", "--name", "test2"]));
203     let value1: Option<String> = args.opt_value_from_str("--name").unwrap();
204     let value2: Option<String> = args.opt_value_from_str("--name").unwrap();
205     assert_eq!(value1.unwrap(), "test1");
206     assert_eq!(value2.unwrap(), "test2");
207 }
208 
209 #[test]
option_from_os_str_01()210 fn option_from_os_str_01() {
211     use std::path::PathBuf;
212 
213     fn parse_path(s: &std::ffi::OsStr) -> Result<PathBuf, &'static str> {
214         Ok(s.into())
215     }
216 
217     let mut args = Arguments::from_vec(to_vec(&["--input", "text.txt"]));
218     let value: Result<Option<PathBuf>, Error> = args.opt_value_from_os_str("--input", parse_path);
219     assert_eq!(value.unwrap().unwrap().display().to_string(), "text.txt");
220 }
221 
222 #[test]
missing_option_value_01()223 fn missing_option_value_01() {
224     let mut args = Arguments::from_vec(to_vec(&["--value"]));
225     let value: Result<Option<u32>, Error> = args.opt_value_from_str("--value");
226     assert_eq!(value.unwrap_err().to_string(),
227                "the '--value' option doesn't have an associated value");
228 }
229 
230 #[test]
missing_option_value_02()231 fn missing_option_value_02() {
232     let mut args = Arguments::from_vec(to_vec(&["--value"]));
233     let value: Result<Option<u32>, Error> = args.opt_value_from_str("--value");
234     assert!(value.is_err()); // ignore error
235     // the `--value` flag should not be removed by the previous command
236     assert!(args.finish().is_err());
237 }
238 
239 #[test]
missing_option_value_03()240 fn missing_option_value_03() {
241     let mut args = Arguments::from_vec(to_vec(&["--value", "q"]));
242     let value: Result<Option<u32>, Error> = args.opt_value_from_str("--value");
243     assert!(value.is_err()); // ignore error
244     // the `--value` flag should not be removed by the previous command
245     assert!(args.finish().is_err());
246 }
247 
248 #[test]
multiple_options_01()249 fn multiple_options_01() {
250     let mut args = Arguments::from_vec(to_vec(&["-w", "10", "-w", "20"]));
251     let value: Vec<u32> = args.values_from_str("-w").unwrap();
252     assert_eq!(value, &[10, 20]);
253 }
254 
255 #[test]
multiple_options_02()256 fn multiple_options_02() {
257     // No values is not an error.
258     let mut args = Arguments::from_vec(to_vec(&[]));
259     let value: Vec<u32> = args.values_from_str("-w").unwrap();
260     assert_eq!(value, &[]);
261 }
262 
263 #[test]
multiple_options_03()264 fn multiple_options_03() {
265     // Argument can be split.
266     let mut args = Arguments::from_vec(to_vec(&["-w", "10", "--other", "-w", "20"]));
267     let value: Vec<u32> = args.values_from_str("-w").unwrap();
268     assert_eq!(value, &[10, 20]);
269 }
270 
271 #[test]
free_01()272 fn free_01() {
273     let args = Arguments::from_vec(to_vec(&[]));
274     assert_eq!(args.free_os().unwrap(), to_vec(&[]));
275 }
276 
277 #[test]
free_02()278 fn free_02() {
279     let args = Arguments::from_vec(to_vec(&["text.txt"]));
280     assert_eq!(args.free_os().unwrap(), to_vec(&["text.txt"]));
281 }
282 
283 #[test]
free_03()284 fn free_03() {
285     let args = Arguments::from_vec(to_vec(&["text.txt", "text2.txt"]));
286     assert_eq!(args.free_os().unwrap(), to_vec(&["text.txt", "text2.txt"]));
287 }
288 
289 #[test]
free_04()290 fn free_04() {
291     let mut args = Arguments::from_vec(to_vec(&["-h", "text.txt", "text2.txt"]));
292     assert!(args.contains("-h"));
293     assert_eq!(args.free_os().unwrap(), to_vec(&["text.txt", "text2.txt"]));
294 }
295 
296 #[test]
free_05()297 fn free_05() {
298     let mut args = Arguments::from_vec(to_vec(&["text.txt", "-h", "text2.txt"]));
299     assert!(args.contains("-h"));
300     assert_eq!(args.free_os().unwrap(), to_vec(&["text.txt", "text2.txt"]));
301 }
302 
303 #[test]
free_06()304 fn free_06() {
305     let mut args = Arguments::from_vec(to_vec(&["text.txt", "text2.txt", "-h"]));
306     assert!(args.contains("-h"));
307     assert_eq!(args.free_os().unwrap(), to_vec(&["text.txt", "text2.txt"]));
308 }
309 
310 #[test]
free_from_fn_01()311 fn free_from_fn_01() {
312     let mut args = Arguments::from_vec(to_vec(&["5"]));
313     assert_eq!(args.free_from_fn(u32::from_str).unwrap(), Some(5));
314 }
315 
316 #[test]
free_from_fn_02()317 fn free_from_fn_02() {
318     let mut args = Arguments::from_vec(to_vec(&[]));
319     assert_eq!(args.free_from_fn(u32::from_str).unwrap(), None);
320 }
321 
322 #[test]
free_from_fn_03()323 fn free_from_fn_03() {
324     let mut args = Arguments::from_vec(to_vec(&["-h"]));
325     assert_eq!(args.free_from_fn(u32::from_str).unwrap_err().to_string(),
326                "unused arguments left: -h");
327 }
328 
329 #[test]
free_from_fn_04()330 fn free_from_fn_04() {
331     let mut args = Arguments::from_vec(to_vec(&["a"]));
332     assert_eq!(args.free_from_fn(u32::from_str).unwrap_err().to_string(),
333                "failed to parse 'a' cause invalid digit found in string");
334 }
335 
336 #[test]
free_from_str_01()337 fn free_from_str_01() {
338     let mut args = Arguments::from_vec(to_vec(&["5"]));
339     let value: Result<Option<u32>, Error> = args.free_from_str();
340     assert_eq!(value.unwrap(), Some(5));
341 }
342 
343 #[test]
unused_args_01()344 fn unused_args_01() {
345     let args = Arguments::from_vec(to_vec(&["-h", "text.txt"]));
346     assert_eq!(args.finish().unwrap_err().to_string(),
347                "unused arguments left: -h, text.txt");
348 }
349 
350 #[test]
unused_args_02()351 fn unused_args_02() {
352     let args = Arguments::from_vec(to_vec(&["-h", "text.txt"]));
353     assert_eq!(args.free().unwrap_err().to_string(),
354                "unused arguments left: -h");
355 }
356 
357 #[test]
stdin()358 fn stdin() {
359     let args = Arguments::from_vec(to_vec(&["-"]));
360     assert_eq!(args.free_os().unwrap(), to_vec(&["-"]));
361 }
362 
363 #[test]
required_option_01()364 fn required_option_01() {
365     let mut args = Arguments::from_vec(to_vec(&["--width", "10"]));
366     let value: u32 = args.value_from_str("--width").unwrap();
367     assert_eq!(value, 10);
368 }
369 
370 #[test]
missing_required_option_01()371 fn missing_required_option_01() {
372     let mut args = Arguments::from_vec(to_vec(&[]));
373     let value: Result<u32, Error> = args.value_from_str("-w");
374     assert_eq!(value.unwrap_err().to_string(),
375                "the '-w' option must be set");
376 }
377 
378 #[test]
missing_required_option_02()379 fn missing_required_option_02() {
380     let mut args = Arguments::from_vec(to_vec(&[]));
381     let value: Result<u32, Error> = args.value_from_str("--width");
382     assert_eq!(value.unwrap_err().to_string(),
383                "the '--width' option must be set");
384 }
385 
386 #[test]
missing_required_option_03()387 fn missing_required_option_03() {
388     let mut args = Arguments::from_vec(to_vec(&[]));
389     let value: Result<u32, Error> = args.value_from_str(["-w", "--width"]);
390     assert_eq!(value.unwrap_err().to_string(),
391                "the '-w/--width' option must be set");
392 }
393 
394 #[test]
subcommand()395 fn subcommand() {
396     let mut args = Arguments::from_vec(to_vec(&["toolchain", "install", "--help"]));
397 
398     let cmd = args.subcommand().unwrap();
399     assert_eq!(cmd, Some("toolchain".to_string()));
400 
401     let cmd = args.subcommand().unwrap();
402     assert_eq!(cmd, Some("install".to_string()));
403 
404     let cmd = args.subcommand().unwrap();
405     assert_eq!(cmd, None);
406 }
407