• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::utils;
2 
3 use clap::{arg, error::ErrorKind, Arg, ArgAction, Command};
4 
5 #[test]
flag_subcommand_normal()6 fn flag_subcommand_normal() {
7     let matches = Command::new("test")
8         .subcommand(
9             Command::new("some").short_flag('S').long_flag("some").arg(
10                 Arg::new("test")
11                     .short('t')
12                     .long("test")
13                     .help("testing testing")
14                     .action(ArgAction::SetTrue),
15             ),
16         )
17         .try_get_matches_from(vec!["myprog", "some", "--test"])
18         .unwrap();
19     assert_eq!(matches.subcommand_name().unwrap(), "some");
20     let sub_matches = matches.subcommand_matches("some").unwrap();
21     assert!(*sub_matches
22         .get_one::<bool>("test")
23         .expect("defaulted by clap"));
24 }
25 
26 #[test]
flag_subcommand_normal_with_alias()27 fn flag_subcommand_normal_with_alias() {
28     let matches = Command::new("test")
29         .subcommand(
30             Command::new("some")
31                 .short_flag('S')
32                 .long_flag("S")
33                 .arg(
34                     Arg::new("test")
35                         .short('t')
36                         .long("test")
37                         .help("testing testing")
38                         .action(ArgAction::SetTrue),
39                 )
40                 .alias("result"),
41         )
42         .try_get_matches_from(vec!["myprog", "result", "--test"])
43         .unwrap();
44     assert_eq!(matches.subcommand_name().unwrap(), "some");
45     let sub_matches = matches.subcommand_matches("some").unwrap();
46     assert!(*sub_matches
47         .get_one::<bool>("test")
48         .expect("defaulted by clap"));
49 }
50 
51 #[test]
flag_subcommand_short()52 fn flag_subcommand_short() {
53     let matches = Command::new("test")
54         .subcommand(
55             Command::new("some").short_flag('S').arg(
56                 Arg::new("test")
57                     .short('t')
58                     .long("test")
59                     .help("testing testing")
60                     .action(ArgAction::SetTrue),
61             ),
62         )
63         .try_get_matches_from(vec!["myprog", "-S", "--test"])
64         .unwrap();
65     assert_eq!(matches.subcommand_name().unwrap(), "some");
66     let sub_matches = matches.subcommand_matches("some").unwrap();
67     assert!(*sub_matches
68         .get_one::<bool>("test")
69         .expect("defaulted by clap"));
70 }
71 
72 #[test]
flag_subcommand_short_with_args()73 fn flag_subcommand_short_with_args() {
74     let matches = Command::new("test")
75         .subcommand(
76             Command::new("some").short_flag('S').arg(
77                 Arg::new("test")
78                     .short('t')
79                     .long("test")
80                     .help("testing testing")
81                     .action(ArgAction::SetTrue),
82             ),
83         )
84         .try_get_matches_from(vec!["myprog", "-St"])
85         .unwrap();
86     assert_eq!(matches.subcommand_name().unwrap(), "some");
87     let sub_matches = matches.subcommand_matches("some").unwrap();
88     assert!(*sub_matches
89         .get_one::<bool>("test")
90         .expect("defaulted by clap"));
91 }
92 
93 #[test]
flag_subcommand_short_with_alias()94 fn flag_subcommand_short_with_alias() {
95     let matches = Command::new("test")
96         .subcommand(
97             Command::new("some")
98                 .short_flag('S')
99                 .arg(
100                     Arg::new("test")
101                         .short('t')
102                         .long("test")
103                         .help("testing testing")
104                         .action(ArgAction::SetTrue),
105                 )
106                 .short_flag_alias('M')
107                 .short_flag_alias('B'),
108         )
109         .try_get_matches_from(vec!["myprog", "-Bt"])
110         .unwrap();
111     assert_eq!(matches.subcommand_name().unwrap(), "some");
112     let sub_matches = matches.subcommand_matches("some").unwrap();
113     assert!(*sub_matches
114         .get_one::<bool>("test")
115         .expect("defaulted by clap"));
116 }
117 
118 #[test]
flag_subcommand_short_with_alias_same_as_short_flag()119 fn flag_subcommand_short_with_alias_same_as_short_flag() {
120     let matches = Command::new("test")
121         .subcommand(Command::new("some").short_flag('S').short_flag_alias('S'))
122         .try_get_matches_from(vec!["myprog", "-S"])
123         .unwrap();
124     assert_eq!(matches.subcommand_name().unwrap(), "some");
125 }
126 
127 #[test]
flag_subcommand_long_with_alias_same_as_long_flag()128 fn flag_subcommand_long_with_alias_same_as_long_flag() {
129     let matches = Command::new("test")
130         .subcommand(
131             Command::new("some")
132                 .long_flag("sync")
133                 .long_flag_alias("sync"),
134         )
135         .try_get_matches_from(vec!["myprog", "--sync"])
136         .unwrap();
137     assert_eq!(matches.subcommand_name().unwrap(), "some");
138 }
139 
140 #[test]
flag_subcommand_short_with_aliases_vis_and_hidden()141 fn flag_subcommand_short_with_aliases_vis_and_hidden() {
142     let cmd = Command::new("test").subcommand(
143         Command::new("some")
144             .short_flag('S')
145             .arg(
146                 Arg::new("test")
147                     .short('t')
148                     .long("test")
149                     .help("testing testing"),
150             )
151             .visible_short_flag_aliases(['M', 'B'])
152             .short_flag_alias('C'),
153     );
154     let app1 = cmd.clone();
155     let matches1 = app1.try_get_matches_from(vec!["test", "-M"]).unwrap();
156     assert_eq!(matches1.subcommand_name().unwrap(), "some");
157 
158     let app2 = cmd.clone();
159     let matches2 = app2.try_get_matches_from(vec!["test", "-C"]).unwrap();
160     assert_eq!(matches2.subcommand_name().unwrap(), "some");
161 
162     let app3 = cmd.clone();
163     let matches3 = app3.try_get_matches_from(vec!["test", "-B"]).unwrap();
164     assert_eq!(matches3.subcommand_name().unwrap(), "some");
165 }
166 
167 #[test]
flag_subcommand_short_with_aliases()168 fn flag_subcommand_short_with_aliases() {
169     let matches = Command::new("test")
170         .subcommand(
171             Command::new("some")
172                 .short_flag('S')
173                 .arg(
174                     Arg::new("test")
175                         .short('t')
176                         .long("test")
177                         .help("testing testing")
178                         .action(ArgAction::SetTrue),
179                 )
180                 .short_flag_aliases(['M', 'B']),
181         )
182         .try_get_matches_from(vec!["myprog", "-Bt"])
183         .unwrap();
184     assert_eq!(matches.subcommand_name().unwrap(), "some");
185     let sub_matches = matches.subcommand_matches("some").unwrap();
186     assert!(*sub_matches
187         .get_one::<bool>("test")
188         .expect("defaulted by clap"));
189 }
190 
191 #[test]
192 #[should_panic]
flag_subcommand_short_with_alias_hyphen()193 fn flag_subcommand_short_with_alias_hyphen() {
194     let _ = Command::new("test")
195         .subcommand(
196             Command::new("some")
197                 .short_flag('S')
198                 .arg(
199                     Arg::new("test")
200                         .short('t')
201                         .long("test")
202                         .help("testing testing"),
203                 )
204                 .short_flag_alias('-'),
205         )
206         .try_get_matches_from(vec!["myprog", "-Bt"])
207         .unwrap();
208 }
209 
210 #[test]
211 #[should_panic]
flag_subcommand_short_with_aliases_hyphen()212 fn flag_subcommand_short_with_aliases_hyphen() {
213     let _ = Command::new("test")
214         .subcommand(
215             Command::new("some")
216                 .short_flag('S')
217                 .arg(
218                     Arg::new("test")
219                         .short('t')
220                         .long("test")
221                         .help("testing testing"),
222                 )
223                 .short_flag_aliases(['-', '-', '-']),
224         )
225         .try_get_matches_from(vec!["myprog", "-Bt"])
226         .unwrap();
227 }
228 
229 #[test]
flag_subcommand_short_after_long_arg()230 fn flag_subcommand_short_after_long_arg() {
231     let m = Command::new("pacman")
232         .subcommand(
233             Command::new("sync")
234                 .short_flag('S')
235                 .arg(Arg::new("clean").short('c').action(ArgAction::SetTrue)),
236         )
237         .arg(Arg::new("arg").long("arg").action(ArgAction::Set))
238         .try_get_matches_from(vec!["pacman", "--arg", "foo", "-Sc"])
239         .unwrap();
240     let subm = m.subcommand_matches("sync");
241     assert!(subm.is_some());
242     let subm = subm.unwrap();
243     assert!(*subm.get_one::<bool>("clean").expect("defaulted by clap"));
244 }
245 
246 #[test]
flag_subcommand_long()247 fn flag_subcommand_long() {
248     let matches = Command::new("test")
249         .subcommand(
250             Command::new("some").long_flag("some").arg(
251                 Arg::new("test")
252                     .short('t')
253                     .long("test")
254                     .help("testing testing")
255                     .action(ArgAction::SetTrue),
256             ),
257         )
258         .try_get_matches_from(vec!["myprog", "--some", "--test"])
259         .unwrap();
260     assert_eq!(matches.subcommand_name().unwrap(), "some");
261     let sub_matches = matches.subcommand_matches("some").unwrap();
262     assert!(*sub_matches
263         .get_one::<bool>("test")
264         .expect("defaulted by clap"));
265 }
266 
267 #[test]
flag_subcommand_long_with_alias()268 fn flag_subcommand_long_with_alias() {
269     let matches = Command::new("test")
270         .subcommand(
271             Command::new("some")
272                 .long_flag("some")
273                 .arg(
274                     Arg::new("test")
275                         .short('t')
276                         .long("test")
277                         .help("testing testing")
278                         .action(ArgAction::SetTrue),
279                 )
280                 .long_flag_alias("result"),
281         )
282         .try_get_matches_from(vec!["myprog", "--result", "--test"])
283         .unwrap();
284     assert_eq!(matches.subcommand_name().unwrap(), "some");
285     let sub_matches = matches.subcommand_matches("some").unwrap();
286     assert!(*sub_matches
287         .get_one::<bool>("test")
288         .expect("defaulted by clap"));
289 }
290 
291 #[test]
flag_subcommand_long_with_aliases()292 fn flag_subcommand_long_with_aliases() {
293     let matches = Command::new("test")
294         .subcommand(
295             Command::new("some")
296                 .long_flag("some")
297                 .arg(
298                     Arg::new("test")
299                         .short('t')
300                         .long("test")
301                         .help("testing testing")
302                         .action(ArgAction::SetTrue),
303                 )
304                 .long_flag_aliases(["result", "someall"]),
305         )
306         .try_get_matches_from(vec!["myprog", "--result", "--test"])
307         .unwrap();
308     assert_eq!(matches.subcommand_name().unwrap(), "some");
309     let sub_matches = matches.subcommand_matches("some").unwrap();
310     assert!(*sub_matches
311         .get_one::<bool>("test")
312         .expect("defaulted by clap"));
313 }
314 
315 #[test]
flag_subcommand_multiple()316 fn flag_subcommand_multiple() {
317     let matches = Command::new("test")
318         .subcommand(
319             Command::new("some")
320                 .short_flag('S')
321                 .long_flag("some")
322                 .arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue))
323                 .arg(arg!(-p --print "print something").action(ArgAction::SetTrue))
324                 .subcommand(
325                     Command::new("result")
326                         .short_flag('R')
327                         .long_flag("result")
328                         .arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue))
329                         .arg(arg!(-p --print "print something").action(ArgAction::SetTrue)),
330                 ),
331         )
332         .try_get_matches_from(vec!["myprog", "-SfpRfp"])
333         .unwrap();
334     assert_eq!(matches.subcommand_name().unwrap(), "some");
335     let sub_matches = matches.subcommand_matches("some").unwrap();
336     assert!(*sub_matches
337         .get_one::<bool>("flag")
338         .expect("defaulted by clap"));
339     assert!(*sub_matches
340         .get_one::<bool>("print")
341         .expect("defaulted by clap"));
342     assert_eq!(sub_matches.subcommand_name().unwrap(), "result");
343     let result_matches = sub_matches.subcommand_matches("result").unwrap();
344     assert!(*result_matches
345         .get_one::<bool>("flag")
346         .expect("defaulted by clap"));
347     assert!(*result_matches
348         .get_one::<bool>("print")
349         .expect("defaulted by clap"));
350 }
351 
352 #[cfg(debug_assertions)]
353 #[test]
354 #[should_panic = "the \'-f\' short flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
flag_subcommand_short_conflict_with_arg()355 fn flag_subcommand_short_conflict_with_arg() {
356     let _ = Command::new("test")
357         .subcommand(Command::new("some").short_flag('f').long_flag("some"))
358         .arg(Arg::new("test").short('f'))
359         .try_get_matches_from(vec!["myprog", "-f"])
360         .unwrap();
361 }
362 
363 #[cfg(debug_assertions)]
364 #[test]
365 #[should_panic = "the \'-f\' short flag is specified for both \'some\' and \'result\' subcommands"]
flag_subcommand_short_conflict_with_alias()366 fn flag_subcommand_short_conflict_with_alias() {
367     let _ = Command::new("test")
368         .subcommand(Command::new("some").short_flag('f').long_flag("some"))
369         .subcommand(Command::new("result").short_flag('t').short_flag_alias('f'))
370         .try_get_matches_from(vec!["myprog", "-f"])
371         .unwrap();
372 }
373 
374 #[cfg(debug_assertions)]
375 #[test]
376 #[should_panic = "the \'--flag\' long flag is specified for both \'some\' and \'result\' subcommands"]
flag_subcommand_long_conflict_with_alias()377 fn flag_subcommand_long_conflict_with_alias() {
378     let _ = Command::new("test")
379         .subcommand(Command::new("some").long_flag("flag"))
380         .subcommand(
381             Command::new("result")
382                 .long_flag("test")
383                 .long_flag_alias("flag"),
384         )
385         .try_get_matches_from(vec!["myprog", "--flag"])
386         .unwrap();
387 }
388 
389 #[cfg(debug_assertions)]
390 #[test]
391 #[should_panic = "the \'-f\' short flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
flag_subcommand_short_conflict_with_arg_alias()392 fn flag_subcommand_short_conflict_with_arg_alias() {
393     let _ = Command::new("test")
394         .subcommand(Command::new("some").short_flag('f').long_flag("some"))
395         .arg(Arg::new("test").short('t').short_alias('f'))
396         .try_get_matches_from(vec!["myprog", "-f"])
397         .unwrap();
398 }
399 
400 #[cfg(debug_assertions)]
401 #[test]
402 #[should_panic = "the \'--some\' long flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
flag_subcommand_long_conflict_with_arg_alias()403 fn flag_subcommand_long_conflict_with_arg_alias() {
404     let _ = Command::new("test")
405         .subcommand(Command::new("some").short_flag('f').long_flag("some"))
406         .arg(Arg::new("test").long("test").alias("some"))
407         .try_get_matches_from(vec!["myprog", "--some"])
408         .unwrap();
409 }
410 
411 #[cfg(debug_assertions)]
412 #[test]
413 #[should_panic = "the \'--flag\' long flag for the \'flag\' argument conflicts with the short flag for \'some\' subcommand"]
flag_subcommand_long_conflict_with_arg()414 fn flag_subcommand_long_conflict_with_arg() {
415     let _ = Command::new("test")
416         .subcommand(Command::new("some").short_flag('a').long_flag("flag"))
417         .arg(Arg::new("flag").long("flag"))
418         .try_get_matches_from(vec!["myprog", "--flag"])
419         .unwrap();
420 }
421 
422 #[test]
423 #[should_panic = "the '--help' long flag for the 'help' argument conflicts with the short flag for 'help' subcommand"]
flag_subcommand_conflict_with_help()424 fn flag_subcommand_conflict_with_help() {
425     let _ = Command::new("test")
426         .subcommand(Command::new("help").short_flag('h').long_flag("help"))
427         .try_get_matches_from(vec!["myprog", "--help"])
428         .unwrap();
429 }
430 
431 #[test]
432 #[cfg(debug_assertions)]
433 #[should_panic = "the '--version' long flag for the 'version' argument conflicts with the short flag for 'ver' subcommand"]
flag_subcommand_conflict_with_version()434 fn flag_subcommand_conflict_with_version() {
435     let _ = Command::new("test")
436         .version("1.0.0")
437         .subcommand(Command::new("ver").short_flag('V').long_flag("version"))
438         .try_get_matches_from(vec!["myprog", "--version"])
439         .unwrap();
440 }
441 
442 #[test]
flag_subcommand_long_infer_pass()443 fn flag_subcommand_long_infer_pass() {
444     let m = Command::new("prog")
445         .infer_subcommands(true)
446         .subcommand(Command::new("test").long_flag("test"))
447         .try_get_matches_from(vec!["prog", "--te"])
448         .unwrap();
449     assert_eq!(m.subcommand_name(), Some("test"));
450 }
451 
452 #[cfg(not(feature = "suggestions"))]
453 #[test]
flag_subcommand_long_infer_fail()454 fn flag_subcommand_long_infer_fail() {
455     let m = Command::new("prog")
456         .infer_subcommands(true)
457         .subcommand(Command::new("test").long_flag("test"))
458         .subcommand(Command::new("temp").long_flag("temp"))
459         .try_get_matches_from(vec!["prog", "--te"]);
460     assert!(m.is_err(), "{:#?}", m.unwrap());
461     assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
462 }
463 
464 #[cfg(feature = "suggestions")]
465 #[test]
flag_subcommand_long_infer_fail()466 fn flag_subcommand_long_infer_fail() {
467     let m = Command::new("prog")
468         .infer_subcommands(true)
469         .subcommand(Command::new("test").long_flag("test"))
470         .subcommand(Command::new("temp").long_flag("temp"))
471         .try_get_matches_from(vec!["prog", "--te"]);
472     assert!(m.is_err(), "{:#?}", m.unwrap());
473     assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
474 }
475 
476 #[test]
flag_subcommand_long_infer_pass_close()477 fn flag_subcommand_long_infer_pass_close() {
478     let m = Command::new("prog")
479         .infer_subcommands(true)
480         .subcommand(Command::new("test").long_flag("test"))
481         .subcommand(Command::new("temp").long_flag("temp"))
482         .try_get_matches_from(vec!["prog", "--tes"])
483         .unwrap();
484     assert_eq!(m.subcommand_name(), Some("test"));
485 }
486 
487 #[test]
flag_subcommand_long_infer_exact_match()488 fn flag_subcommand_long_infer_exact_match() {
489     let m = Command::new("prog")
490         .infer_subcommands(true)
491         .subcommand(Command::new("test").long_flag("test"))
492         .subcommand(Command::new("testa").long_flag("testa"))
493         .subcommand(Command::new("testb").long_flag("testb"))
494         .try_get_matches_from(vec!["prog", "--test"])
495         .unwrap();
496     assert_eq!(m.subcommand_name(), Some("test"));
497 }
498 
499 static FLAG_SUBCOMMAND_HELP: &str = "\
500 Query the package database.
501 
502 Usage: pacman {query|--query|-Q} [OPTIONS]
503 
504 Options:
505   -s, --search <search>...  search locally installed packages for matching strings
506   -i, --info <info>...      view package information
507   -h, --help                Print help
508 ";
509 
510 #[test]
flag_subcommand_long_short_normal_usage_string()511 fn flag_subcommand_long_short_normal_usage_string() {
512     let cmd = Command::new("pacman")
513         .about("package manager utility")
514         .version("5.2.1")
515         .subcommand_required(true)
516         .author("Pacman Development Team")
517         // Query subcommand
518         //
519         // Only a few of its arguments are implemented below.
520         .subcommand(
521             Command::new("query")
522                 .short_flag('Q')
523                 .long_flag("query")
524                 .about("Query the package database.")
525                 .arg(
526                     Arg::new("search")
527                         .short('s')
528                         .long("search")
529                         .help("search locally installed packages for matching strings")
530                         .conflicts_with("info")
531                         .action(ArgAction::Set)
532                         .num_args(1..),
533                 )
534                 .arg(
535                     Arg::new("info")
536                         .long("info")
537                         .short('i')
538                         .conflicts_with("search")
539                         .help("view package information")
540                         .action(ArgAction::Set)
541                         .num_args(1..),
542                 ),
543         );
544     utils::assert_output(cmd, "pacman -Qh", FLAG_SUBCOMMAND_HELP, false);
545 }
546 
547 static FLAG_SUBCOMMAND_NO_SHORT_HELP: &str = "\
548 Query the package database.
549 
550 Usage: pacman {query|--query} [OPTIONS]
551 
552 Options:
553   -s, --search <search>...  search locally installed packages for matching strings
554   -i, --info <info>...      view package information
555   -h, --help                Print help
556 ";
557 
558 #[test]
flag_subcommand_long_normal_usage_string()559 fn flag_subcommand_long_normal_usage_string() {
560     let cmd = Command::new("pacman")
561         .about("package manager utility")
562         .version("5.2.1")
563         .subcommand_required(true)
564         .author("Pacman Development Team")
565         // Query subcommand
566         //
567         // Only a few of its arguments are implemented below.
568         .subcommand(
569             Command::new("query")
570                 .long_flag("query")
571                 .about("Query the package database.")
572                 .arg(
573                     Arg::new("search")
574                         .short('s')
575                         .long("search")
576                         .help("search locally installed packages for matching strings")
577                         .conflicts_with("info")
578                         .action(ArgAction::Set)
579                         .num_args(1..),
580                 )
581                 .arg(
582                     Arg::new("info")
583                         .long("info")
584                         .short('i')
585                         .conflicts_with("search")
586                         .help("view package information")
587                         .action(ArgAction::Set)
588                         .num_args(1..),
589                 ),
590         );
591     utils::assert_output(
592         cmd,
593         "pacman query --help",
594         FLAG_SUBCOMMAND_NO_SHORT_HELP,
595         false,
596     );
597 }
598 
599 static FLAG_SUBCOMMAND_NO_LONG_HELP: &str = "\
600 Query the package database.
601 
602 Usage: pacman {query|-Q} [OPTIONS]
603 
604 Options:
605   -s, --search <search>...  search locally installed packages for matching strings
606   -i, --info <info>...      view package information
607   -h, --help                Print help
608 ";
609 
610 #[test]
flag_subcommand_short_normal_usage_string()611 fn flag_subcommand_short_normal_usage_string() {
612     let cmd = Command::new("pacman")
613         .about("package manager utility")
614         .version("5.2.1")
615         .subcommand_required(true)
616         .author("Pacman Development Team")
617         // Query subcommand
618         //
619         // Only a few of its arguments are implemented below.
620         .subcommand(
621             Command::new("query")
622                 .short_flag('Q')
623                 .about("Query the package database.")
624                 .arg(
625                     Arg::new("search")
626                         .short('s')
627                         .long("search")
628                         .help("search locally installed packages for matching strings")
629                         .conflicts_with("info")
630                         .action(ArgAction::Set)
631                         .num_args(1..),
632                 )
633                 .arg(
634                     Arg::new("info")
635                         .long("info")
636                         .short('i')
637                         .conflicts_with("search")
638                         .help("view package information")
639                         .action(ArgAction::Set)
640                         .num_args(1..),
641                 ),
642         );
643     utils::assert_output(
644         cmd,
645         "pacman query --help",
646         FLAG_SUBCOMMAND_NO_LONG_HELP,
647         false,
648     );
649 }
650