1 use std::ffi::OsStr;
2 use std::ffi::OsString;
3
4 use clap::builder::ArgPredicate;
5 #[cfg(feature = "error-context")]
6 use clap::error::ErrorKind;
7 use clap::{arg, value_parser, Arg, ArgAction, Command};
8
9 #[cfg(feature = "error-context")]
10 use super::utils;
11
12 #[test]
opts()13 fn opts() {
14 let r = Command::new("df")
15 .arg(arg!(o: -o <opt> "some opt").default_value("default"))
16 .try_get_matches_from(vec![""]);
17 assert!(r.is_ok(), "{}", r.unwrap_err());
18 let m = r.unwrap();
19 assert!(m.contains_id("o"));
20 assert_eq!(
21 m.value_source("o").unwrap(),
22 clap::parser::ValueSource::DefaultValue
23 );
24 assert_eq!(
25 m.get_one::<String>("o").map(|v| v.as_str()).unwrap(),
26 "default"
27 );
28 }
29
30 #[test]
default_has_index()31 fn default_has_index() {
32 let r = Command::new("df")
33 .arg(arg!(o: -o <opt> "some opt").default_value("default"))
34 .try_get_matches_from(vec![""]);
35 assert!(r.is_ok(), "{}", r.unwrap_err());
36 let m = r.unwrap();
37 assert_eq!(m.index_of("o"), Some(1));
38 }
39
40 #[test]
41 #[cfg(feature = "error-context")]
opt_without_value_fail()42 fn opt_without_value_fail() {
43 let r = Command::new("df")
44 .arg(
45 arg!(o: -o <opt> "some opt")
46 .default_value("default")
47 .value_parser(clap::builder::NonEmptyStringValueParser::new()),
48 )
49 .try_get_matches_from(vec!["", "-o"]);
50 assert!(r.is_err());
51 let err = r.unwrap_err();
52 assert_eq!(err.kind(), ErrorKind::InvalidValue);
53 assert!(err
54 .to_string()
55 .contains("a value is required for '-o <opt>' but none was supplied"));
56 }
57
58 #[test]
opt_user_override()59 fn opt_user_override() {
60 let r = Command::new("df")
61 .arg(arg!(--opt <FILE> "some arg").default_value("default"))
62 .try_get_matches_from(vec!["", "--opt", "value"]);
63 assert!(r.is_ok(), "{}", r.unwrap_err());
64 let m = r.unwrap();
65 assert!(m.contains_id("opt"));
66 assert_eq!(
67 m.value_source("opt").unwrap(),
68 clap::parser::ValueSource::CommandLine
69 );
70 assert_eq!(
71 m.get_one::<String>("opt").map(|v| v.as_str()).unwrap(),
72 "value"
73 );
74 }
75
76 #[test]
positionals()77 fn positionals() {
78 let r = Command::new("df")
79 .arg(arg!([arg] "some opt").default_value("default"))
80 .try_get_matches_from(vec![""]);
81 assert!(r.is_ok(), "{}", r.unwrap_err());
82 let m = r.unwrap();
83 assert!(m.contains_id("arg"));
84 assert_eq!(
85 m.value_source("arg").unwrap(),
86 clap::parser::ValueSource::DefaultValue
87 );
88 assert_eq!(
89 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
90 "default"
91 );
92 }
93
94 #[test]
positional_user_override()95 fn positional_user_override() {
96 let r = Command::new("df")
97 .arg(arg!([arg] "some arg").default_value("default"))
98 .try_get_matches_from(vec!["", "value"]);
99 assert!(r.is_ok(), "{}", r.unwrap_err());
100 let m = r.unwrap();
101 assert!(m.contains_id("arg"));
102 assert_eq!(
103 m.value_source("arg").unwrap(),
104 clap::parser::ValueSource::CommandLine
105 );
106 assert_eq!(
107 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
108 "value"
109 );
110 }
111
112 // OsStr Default Values
113
114 #[test]
osstr_opts()115 fn osstr_opts() {
116 use std::ffi::OsStr;
117 let expected = OsStr::new("default");
118
119 let r = Command::new("df")
120 .arg(arg!(o: -o <opt> "some opt").default_value(expected))
121 .try_get_matches_from(vec![""]);
122 assert!(r.is_ok(), "{}", r.unwrap_err());
123 let m = r.unwrap();
124 assert!(m.contains_id("o"));
125 assert_eq!(
126 m.get_one::<String>("o").map(|v| v.as_str()).unwrap(),
127 expected
128 );
129 }
130
131 #[test]
osstr_opt_user_override()132 fn osstr_opt_user_override() {
133 use std::ffi::OsStr;
134 let default = OsStr::new("default");
135
136 let r = Command::new("df")
137 .arg(arg!(--opt <FILE> "some arg").default_value(default))
138 .try_get_matches_from(vec!["", "--opt", "value"]);
139 assert!(r.is_ok(), "{}", r.unwrap_err());
140 let m = r.unwrap();
141 assert!(m.contains_id("opt"));
142 assert_eq!(
143 m.get_one::<String>("opt").map(|v| v.as_str()).unwrap(),
144 "value"
145 );
146 }
147
148 #[test]
osstr_positionals()149 fn osstr_positionals() {
150 use std::ffi::OsStr;
151 let expected = OsStr::new("default");
152
153 let r = Command::new("df")
154 .arg(arg!([arg] "some opt").default_value(expected))
155 .try_get_matches_from(vec![""]);
156 assert!(r.is_ok(), "{}", r.unwrap_err());
157 let m = r.unwrap();
158 assert!(m.contains_id("arg"));
159 assert_eq!(
160 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
161 expected
162 );
163 }
164
165 #[test]
osstr_positional_user_override()166 fn osstr_positional_user_override() {
167 use std::ffi::OsStr;
168 let default = OsStr::new("default");
169
170 let r = Command::new("df")
171 .arg(arg!([arg] "some arg").default_value(default))
172 .try_get_matches_from(vec!["", "value"]);
173 assert!(r.is_ok(), "{}", r.unwrap_err());
174 let m = r.unwrap();
175 assert!(m.contains_id("arg"));
176 assert_eq!(
177 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
178 "value"
179 );
180 }
181
182 // --- Default if arg is present
183
184 #[test]
default_if_arg_present_no_default()185 fn default_if_arg_present_no_default() {
186 let r = Command::new("df")
187 .arg(arg!(--opt <FILE> "some arg").required(true))
188 .arg(arg!([arg] "some arg").default_value_if(
189 "opt",
190 ArgPredicate::IsPresent,
191 Some("default"),
192 ))
193 .try_get_matches_from(vec!["", "--opt", "some"]);
194 assert!(r.is_ok(), "{}", r.unwrap_err());
195 let m = r.unwrap();
196 assert!(m.contains_id("arg"));
197 assert_eq!(
198 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
199 "default"
200 );
201 }
202
203 #[test]
default_if_arg_present_no_default_user_override()204 fn default_if_arg_present_no_default_user_override() {
205 let r = Command::new("df")
206 .arg(arg!(--opt <FILE> "some arg"))
207 .arg(arg!([arg] "some arg").default_value_if(
208 "opt",
209 ArgPredicate::IsPresent,
210 Some("default"),
211 ))
212 .try_get_matches_from(vec!["", "--opt", "some", "other"]);
213 assert!(r.is_ok(), "{}", r.unwrap_err());
214 let m = r.unwrap();
215 assert!(m.contains_id("arg"));
216 assert_eq!(
217 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
218 "other"
219 );
220 }
221
222 #[test]
default_if_arg_present_no_arg_with_default()223 fn default_if_arg_present_no_arg_with_default() {
224 let r = Command::new("df")
225 .arg(arg!(--opt <FILE> "some arg"))
226 .arg(
227 arg!([arg] "some arg")
228 .default_value("first")
229 .default_value_if("opt", ArgPredicate::IsPresent, Some("default")),
230 )
231 .try_get_matches_from(vec![""]);
232 assert!(r.is_ok(), "{}", r.unwrap_err());
233 let m = r.unwrap();
234 assert!(m.contains_id("arg"));
235 assert_eq!(
236 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
237 "first"
238 );
239 }
240
241 #[test]
default_if_arg_present_with_default()242 fn default_if_arg_present_with_default() {
243 let r = Command::new("df")
244 .arg(arg!(--opt <FILE> "some arg"))
245 .arg(
246 arg!([arg] "some arg")
247 .default_value("first")
248 .default_value_if("opt", ArgPredicate::IsPresent, Some("default")),
249 )
250 .try_get_matches_from(vec!["", "--opt", "some"]);
251 assert!(r.is_ok(), "{}", r.unwrap_err());
252 let m = r.unwrap();
253 assert!(m.contains_id("arg"));
254 assert_eq!(
255 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
256 "default"
257 );
258 }
259
260 #[test]
default_if_arg_present_with_default_user_override()261 fn default_if_arg_present_with_default_user_override() {
262 let r = Command::new("df")
263 .arg(arg!(--opt <FILE> "some arg"))
264 .arg(
265 arg!([arg] "some arg")
266 .default_value("first")
267 .default_value_if("opt", ArgPredicate::IsPresent, Some("default")),
268 )
269 .try_get_matches_from(vec!["", "--opt", "some", "other"]);
270 assert!(r.is_ok(), "{}", r.unwrap_err());
271 let m = r.unwrap();
272 assert!(m.contains_id("arg"));
273 assert_eq!(
274 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
275 "other"
276 );
277 }
278
279 #[test]
default_if_arg_present_no_arg_with_default_user_override()280 fn default_if_arg_present_no_arg_with_default_user_override() {
281 let r = Command::new("df")
282 .arg(arg!(--opt <FILE> "some arg"))
283 .arg(
284 arg!([arg] "some arg")
285 .default_value("first")
286 .default_value_if("opt", ArgPredicate::IsPresent, Some("default")),
287 )
288 .try_get_matches_from(vec!["", "other"]);
289 assert!(r.is_ok(), "{}", r.unwrap_err());
290 let m = r.unwrap();
291 assert!(m.contains_id("arg"));
292 assert_eq!(
293 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
294 "other"
295 );
296 }
297
298 // Conditional Default Values
299
300 #[test]
default_if_arg_present_with_value_no_default()301 fn default_if_arg_present_with_value_no_default() {
302 let r = Command::new("df")
303 .arg(arg!(--opt <FILE> "some arg"))
304 .arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default")))
305 .try_get_matches_from(vec!["", "--opt", "value"]);
306 assert!(r.is_ok(), "{}", r.unwrap_err());
307 let m = r.unwrap();
308 assert!(m.contains_id("arg"));
309 assert_eq!(
310 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
311 "default"
312 );
313 }
314
315 #[test]
default_if_arg_present_with_value_no_default_fail()316 fn default_if_arg_present_with_value_no_default_fail() {
317 let r = Command::new("df")
318 .arg(arg!(--opt <FILE> "some arg"))
319 .arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default")))
320 .try_get_matches_from(vec!["", "--opt", "other"]);
321 assert!(r.is_ok(), "{}", r.unwrap_err());
322 let m = r.unwrap();
323 assert!(!m.contains_id("arg"));
324 assert!(m.get_one::<String>("arg").map(|v| v.as_str()).is_none());
325 }
326
327 #[test]
default_if_arg_present_with_value_no_default_user_override()328 fn default_if_arg_present_with_value_no_default_user_override() {
329 let r = Command::new("df")
330 .arg(arg!(--opt <FILE> "some arg"))
331 .arg(arg!([arg] "some arg").default_value_if("opt", "some", Some("default")))
332 .try_get_matches_from(vec!["", "--opt", "some", "other"]);
333 assert!(r.is_ok(), "{}", r.unwrap_err());
334 let m = r.unwrap();
335 assert!(m.contains_id("arg"));
336 assert_eq!(
337 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
338 "other"
339 );
340 }
341
342 #[test]
default_if_arg_present_with_value_no_arg_with_default()343 fn default_if_arg_present_with_value_no_arg_with_default() {
344 let r = Command::new("df")
345 .arg(arg!(--opt <FILE> "some arg"))
346 .arg(
347 arg!([arg] "some arg")
348 .default_value("first")
349 .default_value_if("opt", "some", Some("default")),
350 )
351 .try_get_matches_from(vec![""]);
352 assert!(r.is_ok(), "{}", r.unwrap_err());
353 let m = r.unwrap();
354 assert!(m.contains_id("arg"));
355 assert_eq!(
356 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
357 "first"
358 );
359 }
360
361 #[test]
default_if_arg_present_with_value_no_arg_with_default_fail()362 fn default_if_arg_present_with_value_no_arg_with_default_fail() {
363 let r = Command::new("df")
364 .arg(arg!(--opt <FILE> "some arg"))
365 .arg(
366 arg!([arg] "some arg")
367 .default_value("first")
368 .default_value_if("opt", "some", Some("default")),
369 )
370 .try_get_matches_from(vec!["", "--opt", "other"]);
371 assert!(r.is_ok(), "{}", r.unwrap_err());
372 let m = r.unwrap();
373 assert!(m.contains_id("arg"));
374 assert_eq!(
375 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
376 "first"
377 );
378 }
379
380 #[test]
default_if_arg_present_with_value_with_default()381 fn default_if_arg_present_with_value_with_default() {
382 let r = Command::new("df")
383 .arg(arg!(--opt <FILE> "some arg"))
384 .arg(
385 arg!([arg] "some arg")
386 .default_value("first")
387 .default_value_if("opt", "some", Some("default")),
388 )
389 .try_get_matches_from(vec!["", "--opt", "some"]);
390 assert!(r.is_ok(), "{}", r.unwrap_err());
391 let m = r.unwrap();
392 assert!(m.contains_id("arg"));
393 assert_eq!(
394 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
395 "default"
396 );
397 }
398
399 #[test]
default_if_arg_present_with_value_with_default_user_override()400 fn default_if_arg_present_with_value_with_default_user_override() {
401 let r = Command::new("df")
402 .arg(arg!(--opt <FILE> "some arg"))
403 .arg(
404 arg!([arg] "some arg")
405 .default_value("first")
406 .default_value_if("opt", "some", Some("default")),
407 )
408 .try_get_matches_from(vec!["", "--opt", "some", "other"]);
409 assert!(r.is_ok(), "{}", r.unwrap_err());
410 let m = r.unwrap();
411 assert!(m.contains_id("arg"));
412 assert_eq!(
413 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
414 "other"
415 );
416 }
417
418 #[test]
default_if_arg_present_no_arg_with_value_with_default_user_override()419 fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
420 let r = Command::new("df")
421 .arg(arg!(--opt <FILE> "some arg"))
422 .arg(
423 arg!([arg] "some arg")
424 .default_value("first")
425 .default_value_if("opt", "some", Some("default")),
426 )
427 .try_get_matches_from(vec!["", "other"]);
428 assert!(r.is_ok(), "{}", r.unwrap_err());
429 let m = r.unwrap();
430 assert!(m.contains_id("arg"));
431 assert_eq!(
432 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
433 "other"
434 );
435 }
436
437 #[test]
default_if_arg_present_no_arg_with_value_with_default_user_override_fail()438 fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
439 let r = Command::new("df")
440 .arg(arg!(--opt <FILE> "some arg"))
441 .arg(
442 arg!([arg] "some arg")
443 .default_value("first")
444 .default_value_if("opt", "some", Some("default")),
445 )
446 .try_get_matches_from(vec!["", "--opt", "value", "other"]);
447 assert!(r.is_ok(), "{}", r.unwrap_err());
448 let m = r.unwrap();
449 assert!(m.contains_id("arg"));
450 assert_eq!(
451 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
452 "other"
453 );
454 }
455
456 // Unsetting the default
457
458 #[test]
no_default_if_arg_present_with_value_no_default()459 fn no_default_if_arg_present_with_value_no_default() {
460 let r = Command::new("df")
461 .arg(arg!(--opt <FILE> "some arg"))
462 .arg(arg!([arg] "some arg").default_value_if("opt", "value", None))
463 .try_get_matches_from(vec!["", "--opt", "value"]);
464 assert!(r.is_ok(), "{}", r.unwrap_err());
465 let m = r.unwrap();
466 assert!(!m.contains_id("arg"));
467 }
468
469 #[test]
no_default_if_arg_present_with_value_with_default()470 fn no_default_if_arg_present_with_value_with_default() {
471 let r = Command::new("df")
472 .arg(arg!(--opt <FILE> "some arg"))
473 .arg(
474 arg!([arg] "some arg")
475 .default_value("default")
476 .default_value_if("opt", "value", None),
477 )
478 .try_get_matches_from(vec!["", "--opt", "value"]);
479 assert!(r.is_ok(), "{}", r.unwrap_err());
480 let m = r.unwrap();
481 assert!(!m.contains_id("arg"));
482 assert!(m.get_one::<String>("arg").map(|v| v.as_str()).is_none());
483 }
484
485 #[test]
no_default_if_arg_present_with_value_with_default_user_override()486 fn no_default_if_arg_present_with_value_with_default_user_override() {
487 let r = Command::new("df")
488 .arg(arg!(--opt <FILE> "some arg"))
489 .arg(
490 arg!([arg] "some arg")
491 .default_value("default")
492 .default_value_if("opt", "value", None),
493 )
494 .try_get_matches_from(vec!["", "--opt", "value", "other"]);
495 assert!(r.is_ok(), "{}", r.unwrap_err());
496 let m = r.unwrap();
497 assert!(m.contains_id("arg"));
498 assert_eq!(
499 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
500 "other"
501 );
502 }
503
504 #[test]
no_default_if_arg_present_no_arg_with_value_with_default()505 fn no_default_if_arg_present_no_arg_with_value_with_default() {
506 let r = Command::new("df")
507 .arg(arg!(--opt <FILE> "some arg"))
508 .arg(
509 arg!([arg] "some arg")
510 .default_value("default")
511 .default_value_if("opt", "value", None),
512 )
513 .try_get_matches_from(vec!["", "--opt", "other"]);
514 assert!(r.is_ok(), "{}", r.unwrap_err());
515 let m = r.unwrap();
516 assert!(m.contains_id("arg"));
517 assert_eq!(
518 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
519 "default"
520 );
521 }
522
523 // Multiple conditions
524
525 #[test]
default_ifs_arg_present()526 fn default_ifs_arg_present() {
527 let r = Command::new("df")
528 .arg(arg!(--opt <FILE> "some arg"))
529 .arg(arg!(--flag "some arg"))
530 .arg(
531 arg!([arg] "some arg")
532 .default_value("first")
533 .default_value_ifs([
534 ("opt", ArgPredicate::from("some"), Some("default")),
535 ("flag", ArgPredicate::IsPresent, Some("flg")),
536 ]),
537 )
538 .try_get_matches_from(vec!["", "--flag"]);
539 assert!(r.is_ok(), "{}", r.unwrap_err());
540 let m = r.unwrap();
541 assert!(m.contains_id("arg"));
542 assert_eq!(
543 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
544 "flg"
545 );
546 }
547
548 #[test]
no_default_ifs_arg_present()549 fn no_default_ifs_arg_present() {
550 let r = Command::new("df")
551 .arg(arg!(--opt <FILE> "some arg"))
552 .arg(arg!(--flag "some arg"))
553 .arg(
554 arg!([arg] "some arg")
555 .default_value("first")
556 .default_value_ifs([
557 ("opt", ArgPredicate::from("some"), Some("default")),
558 ("flag", ArgPredicate::IsPresent, None),
559 ]),
560 )
561 .try_get_matches_from(vec!["", "--flag"]);
562 assert!(r.is_ok(), "{}", r.unwrap_err());
563 let m = r.unwrap();
564 assert!(!m.contains_id("arg"));
565 assert!(m.get_one::<String>("arg").map(|v| v.as_str()).is_none());
566 }
567
568 #[test]
default_ifs_arg_present_user_override()569 fn default_ifs_arg_present_user_override() {
570 let r = Command::new("df")
571 .arg(arg!(--opt <FILE> "some arg"))
572 .arg(arg!(--flag "some arg"))
573 .arg(
574 arg!([arg] "some arg")
575 .default_value("first")
576 .default_value_ifs([
577 ("opt", ArgPredicate::from("some"), Some("default")),
578 ("flag", ArgPredicate::IsPresent, Some("flg")),
579 ]),
580 )
581 .try_get_matches_from(vec!["", "--flag", "value"]);
582 assert!(r.is_ok(), "{}", r.unwrap_err());
583 let m = r.unwrap();
584 assert!(m.contains_id("arg"));
585 assert_eq!(
586 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
587 "value"
588 );
589 }
590
591 #[test]
default_ifs_arg_present_order()592 fn default_ifs_arg_present_order() {
593 let r = Command::new("df")
594 .arg(arg!(--opt <FILE> "some arg"))
595 .arg(arg!(--flag "some arg"))
596 .arg(
597 arg!([arg] "some arg")
598 .default_value("first")
599 .default_value_ifs([
600 ("opt", ArgPredicate::from("some"), Some("default")),
601 ("flag", ArgPredicate::IsPresent, Some("flg")),
602 ]),
603 )
604 .try_get_matches_from(vec!["", "--opt=some", "--flag"]);
605 assert!(r.is_ok(), "{}", r.unwrap_err());
606 let m = r.unwrap();
607 assert!(m.contains_id("arg"));
608 assert_eq!(
609 m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
610 "default"
611 );
612 }
613
614 #[test]
default_value_ifs_os()615 fn default_value_ifs_os() {
616 let cmd = Command::new("my_cargo")
617 .arg(
618 Arg::new("flag")
619 .long("flag")
620 .value_parser(value_parser!(OsString))
621 .action(ArgAction::Set),
622 )
623 .arg(
624 Arg::new("other")
625 .long("other")
626 .value_parser(value_parser!(OsString))
627 .default_value_ifs([("flag", "标记2", OsStr::new("flag=标记2"))]),
628 );
629 let result = cmd.try_get_matches_from(["my_cargo", "--flag", "标记2"]);
630 assert!(result.is_ok(), "{}", result.unwrap_err());
631 let m = result.unwrap();
632 assert_eq!(
633 m.get_one::<OsString>("flag").map(OsString::as_os_str),
634 Some(OsStr::new("标记2"))
635 );
636 assert_eq!(
637 m.get_one::<OsString>("other").map(OsString::as_os_str),
638 Some(OsStr::new("flag=标记2")),
639 );
640 }
641
642 // Interaction with requires
643
644 #[test]
conditional_reqs_pass()645 fn conditional_reqs_pass() {
646 let m = Command::new("Test cmd")
647 .arg(
648 Arg::new("target")
649 .action(ArgAction::Set)
650 .default_value("file")
651 .long("target"),
652 )
653 .arg(
654 Arg::new("input")
655 .action(ArgAction::Set)
656 .required(true)
657 .long("input"),
658 )
659 .arg(
660 Arg::new("output")
661 .action(ArgAction::Set)
662 .required_if_eq("target", "file")
663 .long("output"),
664 )
665 .try_get_matches_from(vec!["test", "--input", "some", "--output", "other"]);
666
667 assert!(m.is_ok(), "{}", m.unwrap_err());
668 let m = m.unwrap();
669 assert_eq!(
670 m.get_one::<String>("output").map(|v| v.as_str()),
671 Some("other")
672 );
673 assert_eq!(
674 m.get_one::<String>("input").map(|v| v.as_str()),
675 Some("some")
676 );
677 }
678
679 #[test]
multiple_defaults()680 fn multiple_defaults() {
681 let r = Command::new("diff")
682 .arg(
683 Arg::new("files")
684 .long("files")
685 .num_args(2)
686 .default_values(["old", "new"]),
687 )
688 .try_get_matches_from(vec![""]);
689 assert!(r.is_ok(), "{}", r.unwrap_err());
690 let m = r.unwrap();
691 assert!(m.contains_id("files"));
692 assert_eq!(
693 m.get_many::<String>("files").unwrap().collect::<Vec<_>>(),
694 vec!["old", "new"]
695 );
696 }
697
698 #[test]
multiple_defaults_override()699 fn multiple_defaults_override() {
700 let r = Command::new("diff")
701 .arg(
702 Arg::new("files")
703 .long("files")
704 .num_args(2)
705 .default_values(["old", "new"]),
706 )
707 .try_get_matches_from(vec!["", "--files", "other", "mine"]);
708 assert!(r.is_ok(), "{}", r.unwrap_err());
709 let m = r.unwrap();
710 assert!(m.contains_id("files"));
711 assert_eq!(
712 m.get_many::<String>("files").unwrap().collect::<Vec<_>>(),
713 vec!["other", "mine"]
714 );
715 }
716
717 #[test]
718 #[cfg(feature = "error-context")]
default_vals_donnot_show_in_smart_usage()719 fn default_vals_donnot_show_in_smart_usage() {
720 let cmd = Command::new("bug")
721 .arg(
722 Arg::new("foo")
723 .long("config")
724 .action(ArgAction::Set)
725 .default_value("bar"),
726 )
727 .arg(Arg::new("input").required(true));
728
729 utils::assert_output(
730 cmd,
731 "bug",
732 "\
733 error: the following required arguments were not provided:
734 <input>
735
736 Usage: bug <input>
737
738 For more information, try '--help'.
739 ",
740 true,
741 );
742 }
743
744 #[test]
issue_1050_num_vals_and_defaults()745 fn issue_1050_num_vals_and_defaults() {
746 let res = Command::new("hello")
747 .arg(
748 Arg::new("exit-code")
749 .long("exit-code")
750 .action(ArgAction::Set)
751 .num_args(1)
752 .default_value("0"),
753 )
754 .try_get_matches_from(vec!["hello", "--exit-code=1"]);
755 assert!(res.is_ok(), "{}", res.unwrap_err());
756 let m = res.unwrap();
757 assert_eq!(
758 m.get_one::<String>("exit-code").map(|v| v.as_str()),
759 Some("1")
760 );
761 }
762
763 #[test]
required_groups_with_default_values()764 fn required_groups_with_default_values() {
765 use clap::{Arg, ArgGroup, Command};
766
767 let cmd = Command::new("test")
768 .arg(Arg::new("arg").default_value("value"))
769 .group(ArgGroup::new("group").args(["arg"]).required(true));
770
771 let result = cmd.clone().try_get_matches_from(["test"]);
772 assert!(result.is_err());
773
774 let result = cmd.clone().try_get_matches_from(["test", "value"]);
775 assert!(result.is_ok(), "{}", result.unwrap_err());
776 let m = result.unwrap();
777 assert!(m.contains_id("arg"));
778 assert!(m.contains_id("group"));
779 }
780
781 #[test]
required_args_with_default_values()782 fn required_args_with_default_values() {
783 use clap::{Arg, Command};
784
785 let cmd = Command::new("test").arg(Arg::new("arg").required(true).default_value("value"));
786
787 let result = cmd.clone().try_get_matches_from(["test"]);
788 assert!(result.is_err());
789
790 let result = cmd.clone().try_get_matches_from(["test", "value"]);
791 assert!(result.is_ok(), "{}", result.unwrap_err());
792 let m = result.unwrap();
793 assert!(m.contains_id("arg"));
794 }
795
796 #[cfg(debug_assertions)]
797 #[test]
798 #[cfg(feature = "error-context")]
799 #[should_panic = "Argument `arg`'s default_value=\"value\" failed validation: error: invalid value 'value' for '[arg]'"]
default_values_are_possible_values()800 fn default_values_are_possible_values() {
801 use clap::{Arg, Command};
802
803 let _ = Command::new("test")
804 .arg(
805 Arg::new("arg")
806 .value_parser(["one", "two"])
807 .default_value("value"),
808 )
809 .try_get_matches();
810 }
811
812 #[cfg(debug_assertions)]
813 #[test]
814 #[cfg(feature = "error-context")]
815 #[should_panic = "Argument `arg`'s default_value=\"one\" failed validation: error: invalid value 'one' for '[arg]"]
invalid_default_values()816 fn invalid_default_values() {
817 use clap::{Arg, Command};
818
819 let _ = Command::new("test")
820 .arg(
821 Arg::new("arg")
822 .value_parser(clap::value_parser!(u32))
823 .default_value("one"),
824 )
825 .try_get_matches();
826 }
827
828 #[test]
valid_delimited_default_values()829 fn valid_delimited_default_values() {
830 use clap::{Arg, Command};
831
832 Command::new("test")
833 .arg(
834 Arg::new("arg")
835 .value_parser(clap::value_parser!(u32))
836 .value_delimiter(',')
837 .default_value("1,2,3"),
838 )
839 .debug_assert();
840 }
841
842 #[cfg(debug_assertions)]
843 #[test]
844 #[cfg(feature = "error-context")]
845 #[should_panic = "Argument `arg`'s default_value=\"one\" failed validation: error: invalid value 'one' for '[arg]"]
invalid_delimited_default_values()846 fn invalid_delimited_default_values() {
847 use clap::{Arg, Command};
848
849 Command::new("test")
850 .arg(
851 Arg::new("arg")
852 .value_parser(clap::value_parser!(u32))
853 .value_delimiter(',')
854 .default_value("one,two"),
855 )
856 .debug_assert();
857 }
858
859 #[test]
with_value_delimiter()860 fn with_value_delimiter() {
861 let cmd = Command::new("multiple_values").arg(
862 Arg::new("option")
863 .long("option")
864 .help("multiple options")
865 .value_delimiter(';')
866 .default_value("first;second"),
867 );
868
869 let matches = cmd.try_get_matches_from(vec![""]).unwrap();
870
871 assert_eq!(
872 matches
873 .get_many::<String>("option")
874 .unwrap()
875 .map(|v| v.as_str())
876 .collect::<Vec<_>>(),
877 ["first", "second"]
878 );
879 }
880
881 #[test]
missing_with_value_delimiter()882 fn missing_with_value_delimiter() {
883 let cmd = Command::new("program").arg(
884 Arg::new("option")
885 .long("option")
886 .value_delimiter(';')
887 .num_args(0..=1)
888 .default_missing_values(["value1;value2;value3", "value4;value5"]),
889 );
890
891 let matches = cmd
892 .try_get_matches_from(vec!["program", "--option"])
893 .unwrap();
894
895 assert_eq!(
896 matches
897 .get_many::<String>("option")
898 .unwrap()
899 .map(|v| v.as_str())
900 .collect::<Vec<_>>(),
901 ["value1", "value2", "value3", "value4", "value5"]
902 );
903 }
904
905 #[test]
default_independent_of_trailing()906 fn default_independent_of_trailing() {
907 let cmd = Command::new("test")
908 .dont_delimit_trailing_values(true)
909 .arg(Arg::new("pos").required(true))
910 .arg(
911 Arg::new("flag")
912 .long("flag")
913 .default_value("one,two")
914 .value_delimiter(','),
915 );
916
917 // Baseline behavior
918 let m = cmd
919 .clone()
920 .try_get_matches_from(vec!["program", "here"])
921 .unwrap();
922 assert_eq!(
923 m.get_one::<String>("pos").map(|v| v.as_str()).unwrap(),
924 "here"
925 );
926 assert_eq!(
927 m.get_many::<String>("flag")
928 .unwrap()
929 .map(|v| v.as_str())
930 .collect::<Vec<_>>(),
931 ["one", "two"]
932 );
933
934 // Trailing-values behavior should match the baseline
935 let m = cmd
936 .try_get_matches_from(vec!["program", "--", "here"])
937 .unwrap();
938 assert_eq!(
939 m.get_one::<String>("pos").map(|v| v.as_str()).unwrap(),
940 "here"
941 );
942 assert_eq!(
943 m.get_many::<String>("flag")
944 .unwrap()
945 .map(|v| v.as_str())
946 .collect::<Vec<_>>(),
947 ["one", "two"]
948 );
949 }
950