1 use clap::{builder::PossibleValue, error::ErrorKind, Arg, ArgAction, Command};
2
3 #[cfg(feature = "error-context")]
4 use super::utils;
5
6 #[test]
possible_values_of_positional()7 fn possible_values_of_positional() {
8 let m = Command::new("possible_values")
9 .arg(Arg::new("positional").index(1).value_parser(["test123"]))
10 .try_get_matches_from(vec!["myprog", "test123"]);
11
12 assert!(m.is_ok(), "{}", m.unwrap_err());
13 let m = m.unwrap();
14
15 assert!(m.contains_id("positional"));
16 assert_eq!(
17 m.get_one::<String>("positional").map(|v| v.as_str()),
18 Some("test123")
19 );
20 }
21
22 #[test]
possible_value_arg_value()23 fn possible_value_arg_value() {
24 let m = Command::new("possible_values")
25 .arg(
26 Arg::new("arg_value")
27 .index(1)
28 .value_parser([PossibleValue::new("test123")
29 .hide(false)
30 .help("It's just a test")]),
31 )
32 .try_get_matches_from(vec!["myprog", "test123"]);
33
34 assert!(m.is_ok(), "{}", m.unwrap_err());
35 let m = m.unwrap();
36
37 assert!(m.contains_id("arg_value"));
38 assert_eq!(
39 m.get_one::<String>("arg_value").map(|v| v.as_str()),
40 Some("test123")
41 );
42 }
43
44 #[test]
possible_values_of_positional_fail()45 fn possible_values_of_positional_fail() {
46 let m = Command::new("possible_values")
47 .arg(Arg::new("positional").index(1).value_parser(["test123"]))
48 .try_get_matches_from(vec!["myprog", "notest"]);
49
50 assert!(m.is_err());
51 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
52 }
53
54 #[test]
possible_values_of_positional_multiple()55 fn possible_values_of_positional_multiple() {
56 let m = Command::new("possible_values")
57 .arg(
58 Arg::new("positional")
59 .index(1)
60 .action(ArgAction::Set)
61 .value_parser(["test123", "test321"])
62 .num_args(1..),
63 )
64 .try_get_matches_from(vec!["myprog", "test123", "test321"]);
65
66 assert!(m.is_ok(), "{}", m.unwrap_err());
67 let m = m.unwrap();
68
69 assert!(m.contains_id("positional"));
70 assert_eq!(
71 m.get_many::<String>("positional")
72 .unwrap()
73 .map(|v| v.as_str())
74 .collect::<Vec<_>>(),
75 vec!["test123", "test321"]
76 );
77 }
78
79 #[test]
possible_values_of_positional_multiple_fail()80 fn possible_values_of_positional_multiple_fail() {
81 let m = Command::new("possible_values")
82 .arg(
83 Arg::new("positional")
84 .index(1)
85 .action(ArgAction::Set)
86 .value_parser(["test123", "test321"])
87 .num_args(1..),
88 )
89 .try_get_matches_from(vec!["myprog", "test123", "notest"]);
90
91 assert!(m.is_err());
92 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
93 }
94
95 #[test]
possible_values_of_option()96 fn possible_values_of_option() {
97 let m = Command::new("possible_values")
98 .arg(
99 Arg::new("option")
100 .short('o')
101 .long("option")
102 .action(ArgAction::Set)
103 .value_parser(["test123"]),
104 )
105 .try_get_matches_from(vec!["myprog", "--option", "test123"]);
106
107 assert!(m.is_ok(), "{}", m.unwrap_err());
108 let m = m.unwrap();
109
110 assert!(m.contains_id("option"));
111 assert_eq!(
112 m.get_one::<String>("option").map(|v| v.as_str()),
113 Some("test123")
114 );
115 }
116
117 #[test]
possible_values_of_option_fail()118 fn possible_values_of_option_fail() {
119 let m = Command::new("possible_values")
120 .arg(
121 Arg::new("option")
122 .short('o')
123 .long("option")
124 .action(ArgAction::Set)
125 .value_parser(["test123"]),
126 )
127 .try_get_matches_from(vec!["myprog", "--option", "notest"]);
128
129 assert!(m.is_err());
130 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
131 }
132
133 #[test]
possible_values_of_option_multiple()134 fn possible_values_of_option_multiple() {
135 let m = Command::new("possible_values")
136 .arg(
137 Arg::new("option")
138 .short('o')
139 .long("option")
140 .action(ArgAction::Set)
141 .value_parser(["test123", "test321"])
142 .action(ArgAction::Append),
143 )
144 .try_get_matches_from(vec!["", "--option", "test123", "--option", "test321"]);
145
146 assert!(m.is_ok(), "{}", m.unwrap_err());
147 let m = m.unwrap();
148
149 assert!(m.contains_id("option"));
150 assert_eq!(
151 m.get_many::<String>("option")
152 .unwrap()
153 .map(|v| v.as_str())
154 .collect::<Vec<_>>(),
155 vec!["test123", "test321"]
156 );
157 }
158
159 #[test]
possible_values_of_option_multiple_fail()160 fn possible_values_of_option_multiple_fail() {
161 let m = Command::new("possible_values")
162 .arg(
163 Arg::new("option")
164 .short('o')
165 .long("option")
166 .action(ArgAction::Set)
167 .value_parser(["test123", "test321"])
168 .action(ArgAction::Append),
169 )
170 .try_get_matches_from(vec!["", "--option", "test123", "--option", "notest"]);
171
172 assert!(m.is_err());
173 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
174 }
175
176 #[test]
177 #[cfg(feature = "error-context")]
possible_values_output()178 fn possible_values_output() {
179 #[cfg(feature = "suggestions")]
180 static PV_ERROR: &str = "\
181 error: invalid value 'slo' for '-O <option>'
182 [possible values: slow, fast, \"ludicrous speed\"]
183
184 note: value 'slow' exists
185
186 For more information, try '--help'.
187 ";
188
189 #[cfg(not(feature = "suggestions"))]
190 static PV_ERROR: &str = "\
191 error: invalid value 'slo' for '-O <option>'
192 [possible values: slow, fast, \"ludicrous speed\"]
193
194 For more information, try '--help'.
195 ";
196
197 utils::assert_output(
198 Command::new("test").arg(
199 Arg::new("option")
200 .short('O')
201 .action(ArgAction::Set)
202 .value_parser(["slow", "fast", "ludicrous speed"]),
203 ),
204 "clap-test -O slo",
205 PV_ERROR,
206 true,
207 );
208 }
209
210 #[test]
211 #[cfg(feature = "error-context")]
possible_values_alias_output()212 fn possible_values_alias_output() {
213 #[cfg(feature = "suggestions")]
214 static PV_ERROR: &str = "\
215 error: invalid value 'slo' for '-O <option>'
216 [possible values: slow, fast, \"ludicrous speed\"]
217
218 note: value 'slow' exists
219
220 For more information, try '--help'.
221 ";
222
223 #[cfg(not(feature = "suggestions"))]
224 static PV_ERROR: &str = "\
225 error: invalid value 'slo' for '-O <option>'
226 [possible values: slow, fast, \"ludicrous speed\"]
227
228 For more information, try '--help'.
229 ";
230
231 utils::assert_output(
232 Command::new("test").arg(
233 Arg::new("option")
234 .short('O')
235 .action(ArgAction::Set)
236 .value_parser([
237 "slow".into(),
238 PossibleValue::new("fast").alias("fost"),
239 PossibleValue::new("ludicrous speed").aliases(["ls", "lcs"]),
240 ]),
241 ),
242 "clap-test -O slo",
243 PV_ERROR,
244 true,
245 );
246 }
247
248 #[test]
249 #[cfg(feature = "error-context")]
possible_values_hidden_output()250 fn possible_values_hidden_output() {
251 #[cfg(feature = "suggestions")]
252 static PV_ERROR: &str = "\
253 error: invalid value 'slo' for '-O <option>'
254 [possible values: slow, fast, \"ludicrous speed\"]
255
256 note: value 'slow' exists
257
258 For more information, try '--help'.
259 ";
260
261 #[cfg(not(feature = "suggestions"))]
262 static PV_ERROR: &str = "\
263 error: invalid value 'slo' for '-O <option>'
264 [possible values: slow, fast, \"ludicrous speed\"]
265
266 For more information, try '--help'.
267 ";
268
269 utils::assert_output(
270 Command::new("test").arg(
271 Arg::new("option")
272 .short('O')
273 .action(ArgAction::Set)
274 .value_parser([
275 "slow".into(),
276 "fast".into(),
277 PossibleValue::new("ludicrous speed"),
278 PossibleValue::new("forbidden speed").hide(true),
279 ]),
280 ),
281 "clap-test -O slo",
282 PV_ERROR,
283 true,
284 );
285 }
286
287 #[test]
288 #[cfg(feature = "error-context")]
escaped_possible_values_output()289 fn escaped_possible_values_output() {
290 #[cfg(feature = "suggestions")]
291 static PV_ERROR_ESCAPED: &str = "\
292 error: invalid value 'ludicrous' for '-O <option>'
293 [possible values: slow, fast, \"ludicrous speed\"]
294
295 note: value 'ludicrous speed' exists
296
297 For more information, try '--help'.
298 ";
299
300 #[cfg(not(feature = "suggestions"))]
301 static PV_ERROR_ESCAPED: &str = "\
302 error: invalid value 'ludicrous' for '-O <option>'
303 [possible values: slow, fast, \"ludicrous speed\"]
304
305 For more information, try '--help'.
306 ";
307
308 utils::assert_output(
309 Command::new("test").arg(
310 Arg::new("option")
311 .short('O')
312 .action(ArgAction::Set)
313 .value_parser(["slow", "fast", "ludicrous speed"]),
314 ),
315 "clap-test -O ludicrous",
316 PV_ERROR_ESCAPED,
317 true,
318 );
319 }
320
321 #[test]
322 #[cfg(feature = "error-context")]
missing_possible_value_error()323 fn missing_possible_value_error() {
324 static MISSING_PV_ERROR: &str = "\
325 error: a value is required for '-O <option>' but none was supplied
326 [possible values: slow, fast, \"ludicrous speed\"]
327
328 For more information, try '--help'.
329 ";
330
331 utils::assert_output(
332 Command::new("test").arg(
333 Arg::new("option")
334 .short('O')
335 .action(ArgAction::Set)
336 .value_parser([
337 "slow".into(),
338 PossibleValue::new("fast").alias("fost"),
339 PossibleValue::new("ludicrous speed"),
340 PossibleValue::new("forbidden speed").hide(true),
341 ]),
342 ),
343 "clap-test -O",
344 MISSING_PV_ERROR,
345 true,
346 );
347 }
348
349 #[test]
alias()350 fn alias() {
351 let m = Command::new("pv")
352 .arg(
353 Arg::new("option")
354 .short('o')
355 .long("option")
356 .action(ArgAction::Set)
357 .value_parser([PossibleValue::new("test123").alias("123"), "test321".into()])
358 .ignore_case(true),
359 )
360 .try_get_matches_from(vec!["pv", "--option", "123"]);
361
362 assert!(m.is_ok(), "{}", m.unwrap_err());
363 assert!(m
364 .unwrap()
365 .get_one::<String>("option")
366 .map(|v| v.as_str())
367 .unwrap()
368 .eq("123"));
369 }
370
371 #[test]
aliases()372 fn aliases() {
373 let m = Command::new("pv")
374 .arg(
375 Arg::new("option")
376 .short('o')
377 .long("option")
378 .action(ArgAction::Set)
379 .value_parser([
380 PossibleValue::new("test123").aliases(["1", "2", "3"]),
381 "test321".into(),
382 ])
383 .ignore_case(true),
384 )
385 .try_get_matches_from(vec!["pv", "--option", "2"]);
386
387 assert!(m.is_ok(), "{}", m.unwrap_err());
388 assert!(m
389 .unwrap()
390 .get_one::<String>("option")
391 .map(|v| v.as_str())
392 .unwrap()
393 .eq("2"));
394 }
395
396 #[test]
ignore_case()397 fn ignore_case() {
398 let m = Command::new("pv")
399 .arg(
400 Arg::new("option")
401 .short('o')
402 .long("option")
403 .action(ArgAction::Set)
404 .value_parser(["test123", "test321"])
405 .ignore_case(true),
406 )
407 .try_get_matches_from(vec!["pv", "--option", "TeSt123"]);
408
409 assert!(m.is_ok(), "{}", m.unwrap_err());
410 assert!(m
411 .unwrap()
412 .get_one::<String>("option")
413 .map(|v| v.as_str())
414 .unwrap()
415 .eq_ignore_ascii_case("test123"));
416 }
417
418 #[test]
ignore_case_fail()419 fn ignore_case_fail() {
420 let m = Command::new("pv")
421 .arg(
422 Arg::new("option")
423 .short('o')
424 .long("option")
425 .action(ArgAction::Set)
426 .value_parser(["test123", "test321"]),
427 )
428 .try_get_matches_from(vec!["pv", "--option", "TeSt123"]);
429
430 assert!(m.is_err());
431 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
432 }
433
434 #[test]
ignore_case_multiple()435 fn ignore_case_multiple() {
436 let m = Command::new("pv")
437 .arg(
438 Arg::new("option")
439 .short('o')
440 .long("option")
441 .action(ArgAction::Set)
442 .value_parser(["test123", "test321"])
443 .num_args(1..)
444 .ignore_case(true),
445 )
446 .try_get_matches_from(vec!["pv", "--option", "TeSt123", "teST123", "tESt321"]);
447
448 assert!(m.is_ok(), "{}", m.unwrap_err());
449 assert_eq!(
450 m.unwrap()
451 .get_many::<String>("option")
452 .unwrap()
453 .map(|v| v.as_str())
454 .collect::<Vec<_>>(),
455 ["TeSt123", "teST123", "tESt321"]
456 );
457 }
458
459 #[test]
ignore_case_multiple_fail()460 fn ignore_case_multiple_fail() {
461 let m = Command::new("pv")
462 .arg(
463 Arg::new("option")
464 .short('o')
465 .long("option")
466 .action(ArgAction::Set)
467 .value_parser(["test123", "test321"])
468 .num_args(1..),
469 )
470 .try_get_matches_from(vec!["pv", "--option", "test123", "teST123", "test321"]);
471
472 assert!(m.is_err());
473 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
474 }
475