• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use clap::{arg, Arg, ArgAction, Command};
2 
3 #[test]
opt_missing()4 fn opt_missing() {
5     let r = Command::new("df")
6         .arg(
7             Arg::new("color")
8                 .long("color")
9                 .default_value("auto")
10                 .num_args(0..=1)
11                 .require_equals(true)
12                 .default_missing_value("always"),
13         )
14         .try_get_matches_from(vec![""]);
15     assert!(r.is_ok(), "{}", r.unwrap_err());
16     let m = r.unwrap();
17     assert!(m.contains_id("color"));
18     assert_eq!(
19         m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
20         "auto"
21     );
22     assert_eq!(
23         m.value_source("color").unwrap(),
24         clap::parser::ValueSource::DefaultValue
25     );
26     assert_eq!(m.index_of("color"), Some(1));
27 }
28 
29 #[test]
opt_present_with_missing_value()30 fn opt_present_with_missing_value() {
31     let r = Command::new("df")
32         .arg(
33             Arg::new("color")
34                 .long("color")
35                 .default_value("auto")
36                 .num_args(0..=1)
37                 .require_equals(true)
38                 .default_missing_value("always"),
39         )
40         .try_get_matches_from(vec!["", "--color"]);
41     assert!(r.is_ok(), "{}", r.unwrap_err());
42     let m = r.unwrap();
43     assert!(m.contains_id("color"));
44     assert_eq!(
45         m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
46         "always"
47     );
48     assert_eq!(
49         m.value_source("color").unwrap(),
50         clap::parser::ValueSource::CommandLine
51     );
52     assert_eq!(m.index_of("color"), Some(2));
53 }
54 
55 #[test]
opt_present_with_value()56 fn opt_present_with_value() {
57     let r = Command::new("df")
58         .arg(
59             Arg::new("color")
60                 .long("color")
61                 .default_value("auto")
62                 .num_args(0..=1)
63                 .require_equals(true)
64                 .default_missing_value("always"),
65         )
66         .try_get_matches_from(vec!["", "--color=never"]);
67     assert!(r.is_ok(), "{}", r.unwrap_err());
68     let m = r.unwrap();
69     assert!(m.contains_id("color"));
70     assert_eq!(
71         m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
72         "never"
73     );
74     assert_eq!(
75         m.value_source("color").unwrap(),
76         clap::parser::ValueSource::CommandLine
77     );
78     assert_eq!(m.index_of("color"), Some(2));
79 }
80 
81 #[test]
opt_present_with_empty_value()82 fn opt_present_with_empty_value() {
83     let r = Command::new("df")
84         .arg(
85             Arg::new("color")
86                 .long("color")
87                 .default_value("auto")
88                 .require_equals(true)
89                 .default_missing_value("always"),
90         )
91         .try_get_matches_from(vec!["", "--color="]);
92     assert!(r.is_ok(), "{}", r.unwrap_err());
93     let m = r.unwrap();
94     assert!(m.contains_id("color"));
95     assert_eq!(
96         m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
97         ""
98     );
99     assert_eq!(
100         m.value_source("color").unwrap(),
101         clap::parser::ValueSource::CommandLine
102     );
103     assert_eq!(m.index_of("color"), Some(2));
104 }
105 
106 //## `default_value`/`default_missing_value` non-interaction checks
107 
108 #[test]
opt_default()109 fn opt_default() {
110     // assert no change to usual argument handling when adding default_missing_value()
111     let r = Command::new("cmd")
112         .arg(
113             arg!(o: -o [opt] "some opt")
114                 .default_value("default")
115                 .default_missing_value("default_missing"),
116         )
117         .try_get_matches_from(vec![""]);
118     assert!(r.is_ok(), "{}", r.unwrap_err());
119     let m = r.unwrap();
120     assert!(m.contains_id("o"));
121     assert_eq!(
122         m.get_one::<String>("o").map(|v| v.as_str()).unwrap(),
123         "default"
124     );
125 }
126 
127 #[test]
opt_default_user_override()128 fn opt_default_user_override() {
129     // assert no change to usual argument handling when adding default_missing_value()
130     let r = Command::new("cmd")
131         .arg(
132             arg!(o: -o [opt] "some opt")
133                 .default_value("default")
134                 .default_missing_value("default_missing"),
135         )
136         .try_get_matches_from(vec!["", "-o=value"]);
137     assert!(r.is_ok(), "{}", r.unwrap_err());
138     let m = r.unwrap();
139     assert!(m.contains_id("o"));
140     assert_eq!(
141         m.get_one::<String>("o").map(|v| v.as_str()).unwrap(),
142         "value"
143     );
144 }
145 
146 #[test]
default_missing_value_per_occurrence()147 fn default_missing_value_per_occurrence() {
148     // assert no change to usual argument handling when adding default_missing_value()
149     let r = Command::new("cmd")
150         .arg(
151             arg!(o: -o [opt] ... "some opt")
152                 .default_value("default")
153                 .default_missing_value("default_missing"),
154         )
155         .try_get_matches_from(vec!["", "-o", "-o=value", "-o"]);
156     assert!(r.is_ok(), "{}", r.unwrap_err());
157     let m = r.unwrap();
158     assert_eq!(
159         m.get_many::<String>("o")
160             .unwrap()
161             .map(|v| v.as_str())
162             .collect::<Vec<_>>(),
163         vec!["default_missing", "value", "default_missing"]
164     );
165 }
166 
167 #[test]
168 #[allow(clippy::bool_assert_comparison)]
default_missing_value_flag_value()169 fn default_missing_value_flag_value() {
170     let cmd = Command::new("test").arg(
171         Arg::new("flag")
172             .long("flag")
173             .action(ArgAction::Set)
174             .num_args(0..=1)
175             .default_value("false")
176             .default_missing_value("true"),
177     );
178 
179     let m = cmd.clone().try_get_matches_from(["test"]).unwrap();
180     assert!(m.contains_id("flag"));
181     assert_eq!(
182         m.get_one::<String>("flag").map(|v| v.as_str()),
183         Some("false")
184     );
185     assert_eq!(
186         m.value_source("flag").unwrap(),
187         clap::parser::ValueSource::DefaultValue
188     );
189 
190     let m = cmd
191         .clone()
192         .try_get_matches_from(["test", "--flag"])
193         .unwrap();
194     assert!(m.contains_id("flag"));
195     assert_eq!(
196         m.get_one::<String>("flag").map(|v| v.as_str()),
197         Some("true")
198     );
199     assert_eq!(
200         m.value_source("flag").unwrap(),
201         clap::parser::ValueSource::CommandLine
202     );
203 
204     let m = cmd
205         .clone()
206         .try_get_matches_from(["test", "--flag=true"])
207         .unwrap();
208     assert!(m.contains_id("flag"));
209     assert_eq!(
210         m.get_one::<String>("flag").map(|v| v.as_str()),
211         Some("true")
212     );
213     assert_eq!(
214         m.value_source("flag").unwrap(),
215         clap::parser::ValueSource::CommandLine
216     );
217 
218     let m = cmd.try_get_matches_from(["test", "--flag=false"]).unwrap();
219     assert!(m.contains_id("flag"));
220     assert_eq!(
221         m.get_one::<String>("flag").map(|v| v.as_str()),
222         Some("false")
223     );
224     assert_eq!(
225         m.value_source("flag").unwrap(),
226         clap::parser::ValueSource::CommandLine
227     );
228 }
229 
230 #[test]
delimited_missing_value()231 fn delimited_missing_value() {
232     let cmd = Command::new("test").arg(
233         Arg::new("flag")
234             .long("flag")
235             .default_value("one,two")
236             .default_missing_value("three,four")
237             .num_args(0..)
238             .value_delimiter(',')
239             .require_equals(true),
240     );
241 
242     let m = cmd.clone().try_get_matches_from(["test"]).unwrap();
243     assert_eq!(
244         m.get_many::<String>("flag")
245             .unwrap()
246             .map(|s| s.as_str())
247             .collect::<Vec<_>>(),
248         vec!["one", "two"]
249     );
250 
251     let m = cmd.try_get_matches_from(["test", "--flag"]).unwrap();
252     assert_eq!(
253         m.get_many::<String>("flag")
254             .unwrap()
255             .map(|s| s.as_str())
256             .collect::<Vec<_>>(),
257         vec!["three", "four"]
258     );
259 }
260 
261 #[cfg(debug_assertions)]
262 #[test]
263 #[cfg(feature = "error-context")]
264 #[should_panic = "Argument `arg`'s default_missing_value=\"value\" failed validation: error: invalid value 'value' for '[arg]'"]
default_missing_values_are_possible_values()265 fn default_missing_values_are_possible_values() {
266     use clap::{Arg, Command};
267 
268     let _ = Command::new("test")
269         .arg(
270             Arg::new("arg")
271                 .value_parser(["one", "two"])
272                 .default_missing_value("value"),
273         )
274         .try_get_matches();
275 }
276 
277 #[cfg(debug_assertions)]
278 #[test]
279 #[cfg(feature = "error-context")]
280 #[should_panic = "Argument `arg`'s default_missing_value=\"value\" failed validation: error: invalid value 'value' for '[arg]"]
default_missing_values_are_valid()281 fn default_missing_values_are_valid() {
282     use clap::{Arg, Command};
283 
284     let _ = Command::new("test")
285         .arg(
286             Arg::new("arg")
287                 .value_parser(clap::value_parser!(u32))
288                 .default_missing_value("value"),
289         )
290         .try_get_matches();
291 }
292 
293 #[test]
valid_index()294 fn valid_index() {
295     let m = Command::new("df")
296         .arg(
297             Arg::new("color")
298                 .long("color")
299                 .default_value("auto")
300                 .num_args(0..=1)
301                 .require_equals(true)
302                 .default_missing_value("always"),
303         )
304         .arg(Arg::new("sync").long("sync").action(ArgAction::SetTrue))
305         .try_get_matches_from(vec!["df", "--color", "--sync"])
306         .unwrap();
307     assert!(m.contains_id("color"));
308     assert_eq!(
309         m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
310         "always"
311     );
312     assert_eq!(
313         m.value_source("color").unwrap(),
314         clap::parser::ValueSource::CommandLine
315     );
316 
317     // Make sure the index reflects `--color`s position and not something else
318     assert_eq!(m.index_of("color"), Some(2));
319 }
320