• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use clap::{Arg, ArgAction, ArgMatches, Command};
2 
get_app() -> Command3 fn get_app() -> Command {
4     Command::new("myprog")
5         .arg(
6             Arg::new("GLOBAL_ARG")
7                 .long("global-arg")
8                 .help("Specifies something needed by the subcommands")
9                 .global(true)
10                 .action(ArgAction::Set)
11                 .default_value("default_value"),
12         )
13         .arg(
14             Arg::new("GLOBAL_FLAG")
15                 .long("global-flag")
16                 .help("Specifies something needed by the subcommands")
17                 .global(true)
18                 .action(ArgAction::Count),
19         )
20         .subcommand(Command::new("outer").subcommand(Command::new("inner")))
21 }
22 
get_matches(cmd: Command, argv: &'static str) -> ArgMatches23 fn get_matches(cmd: Command, argv: &'static str) -> ArgMatches {
24     cmd.try_get_matches_from(argv.split(' ').collect::<Vec<_>>())
25         .unwrap()
26 }
27 
get_outer_matches(m: &ArgMatches) -> &ArgMatches28 fn get_outer_matches(m: &ArgMatches) -> &ArgMatches {
29     m.subcommand_matches("outer")
30         .expect("could not access outer subcommand")
31 }
32 
get_inner_matches(m: &ArgMatches) -> &ArgMatches33 fn get_inner_matches(m: &ArgMatches) -> &ArgMatches {
34     get_outer_matches(m)
35         .subcommand_matches("inner")
36         .expect("could not access inner subcommand")
37 }
38 
top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool39 fn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
40     m.get_one::<String>("GLOBAL_ARG").map(|v| v.as_str()) == val.into()
41 }
42 
inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool43 fn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
44     get_inner_matches(m)
45         .get_one::<String>("GLOBAL_ARG")
46         .map(|v| v.as_str())
47         == val.into()
48 }
49 
outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool50 fn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
51     get_outer_matches(m)
52         .get_one::<String>("GLOBAL_ARG")
53         .map(|v| v.as_str())
54         == val.into()
55 }
56 
top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool57 fn top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
58     (m.contains_id("GLOBAL_FLAG") == present)
59         && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
60 }
61 
inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool62 fn inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
63     let m = get_inner_matches(m);
64     (m.contains_id("GLOBAL_FLAG") == present)
65         && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
66 }
67 
outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool68 fn outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
69     let m = get_outer_matches(m);
70     (m.contains_id("GLOBAL_FLAG") == present)
71         && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
72 }
73 
74 #[test]
global_arg_used_top_level()75 fn global_arg_used_top_level() {
76     let m = get_matches(get_app(), "myprog --global-arg=some_value outer inner");
77 
78     assert!(top_can_access_arg(&m, "some_value"));
79     assert!(inner_can_access_arg(&m, "some_value"));
80     assert!(outer_can_access_arg(&m, "some_value"));
81 }
82 
83 #[test]
global_arg_used_outer()84 fn global_arg_used_outer() {
85     let m = get_matches(get_app(), "myprog outer --global-arg=some_value inner");
86 
87     assert!(top_can_access_arg(&m, "some_value"));
88     assert!(inner_can_access_arg(&m, "some_value"));
89     assert!(outer_can_access_arg(&m, "some_value"));
90 }
91 
92 #[test]
global_arg_used_inner()93 fn global_arg_used_inner() {
94     let m = get_matches(get_app(), "myprog outer inner --global-arg=some_value");
95 
96     assert!(top_can_access_arg(&m, "some_value"));
97     assert!(inner_can_access_arg(&m, "some_value"));
98     assert!(outer_can_access_arg(&m, "some_value"));
99 }
100 
101 #[test]
global_arg_default_value()102 fn global_arg_default_value() {
103     let m = get_matches(get_app(), "myprog outer inner");
104 
105     assert!(top_can_access_arg(&m, "default_value"));
106     assert!(inner_can_access_arg(&m, "default_value"));
107     assert!(outer_can_access_arg(&m, "default_value"));
108 }
109 
110 #[test]
global_flag_used_top_level()111 fn global_flag_used_top_level() {
112     let m = get_matches(get_app(), "myprog --global-flag outer inner");
113 
114     assert!(top_can_access_flag(&m, true, 1));
115     assert!(inner_can_access_flag(&m, true, 1));
116     assert!(outer_can_access_flag(&m, true, 1));
117 }
118 
119 #[test]
global_flag_used_outer()120 fn global_flag_used_outer() {
121     let m = get_matches(get_app(), "myprog outer --global-flag inner");
122 
123     assert!(top_can_access_flag(&m, true, 1));
124     assert!(inner_can_access_flag(&m, true, 1));
125     assert!(outer_can_access_flag(&m, true, 1));
126 }
127 
128 #[test]
global_flag_used_inner()129 fn global_flag_used_inner() {
130     let m = get_matches(get_app(), "myprog outer inner --global-flag");
131 
132     assert!(top_can_access_flag(&m, true, 1));
133     assert!(inner_can_access_flag(&m, true, 1));
134     assert!(outer_can_access_flag(&m, true, 1));
135 }
136 
137 #[test]
global_flag_2x_used_top_level()138 fn global_flag_2x_used_top_level() {
139     let m = get_matches(get_app(), "myprog --global-flag --global-flag outer inner");
140 
141     assert!(top_can_access_flag(&m, true, 2));
142     assert!(inner_can_access_flag(&m, true, 2));
143     assert!(outer_can_access_flag(&m, true, 2));
144 }
145 
146 #[test]
global_flag_2x_used_inner()147 fn global_flag_2x_used_inner() {
148     let m = get_matches(get_app(), "myprog outer inner --global-flag --global-flag");
149 
150     assert!(top_can_access_flag(&m, true, 2));
151     assert!(inner_can_access_flag(&m, true, 2));
152     assert!(outer_can_access_flag(&m, true, 2));
153 }
154