• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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