1 mod arg { 2 #[test] name_explicit()3 fn name_explicit() { 4 let arg = clap::arg!(foo: --bar <NUM>); 5 assert_eq!(arg.get_id(), "foo"); 6 assert_eq!(arg.get_long(), Some("bar")); 7 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 8 assert!(!arg.is_required_set()); 9 } 10 11 #[test] name_from_long()12 fn name_from_long() { 13 let arg = clap::arg!(--bar <NUM>); 14 assert_eq!(arg.get_id(), "bar"); 15 assert_eq!(arg.get_long(), Some("bar")); 16 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 17 assert!(!arg.is_required_set()); 18 } 19 20 #[test] name_from_value()21 fn name_from_value() { 22 let arg = clap::arg!(<NUM>); 23 assert_eq!(arg.get_id(), "NUM"); 24 assert_eq!(arg.get_long(), None); 25 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 26 assert!(arg.is_required_set()); 27 } 28 29 #[test] 30 #[should_panic] name_none_fails()31 fn name_none_fails() { 32 clap::arg!("Help"); 33 } 34 35 #[test] 36 #[should_panic] short_only_fails()37 fn short_only_fails() { 38 clap::arg!(-b); 39 } 40 41 #[test] short()42 fn short() { 43 let arg = clap::arg!(foo: -b); 44 assert_eq!(arg.get_id(), "foo"); 45 assert_eq!(arg.get_short(), Some('b')); 46 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 47 assert_eq!(arg.get_num_args(), None); 48 assert!(!arg.is_required_set()); 49 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 50 51 let arg = clap::arg!(foo: -'b'); 52 assert_eq!(arg.get_id(), "foo"); 53 assert_eq!(arg.get_short(), Some('b')); 54 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 55 assert_eq!(arg.get_num_args(), None); 56 assert!(!arg.is_required_set()); 57 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 58 59 let arg = clap::arg!(foo: -b ...); 60 assert_eq!(arg.get_id(), "foo"); 61 assert_eq!(arg.get_short(), Some('b')); 62 assert!(matches!(arg.get_action(), clap::ArgAction::Count)); 63 assert_eq!(arg.get_num_args(), None); 64 assert!(!arg.is_required_set()); 65 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 66 67 let arg = clap::arg!(foo: -b "How to use it"); 68 assert_eq!(arg.get_id(), "foo"); 69 assert_eq!(arg.get_short(), Some('b')); 70 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 71 assert_eq!(arg.get_num_args(), None); 72 assert!(!arg.is_required_set()); 73 assert_eq!( 74 arg.get_help().map(|s| s.to_string()), 75 Some("How to use it".to_owned()) 76 ); 77 } 78 79 #[test] short_and_long()80 fn short_and_long() { 81 let arg = clap::arg!(foo: -b --hello); 82 assert_eq!(arg.get_id(), "foo"); 83 assert_eq!(arg.get_long(), Some("hello")); 84 assert_eq!(arg.get_short(), Some('b')); 85 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 86 assert_eq!(arg.get_num_args(), None); 87 assert!(!arg.is_required_set()); 88 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 89 90 let arg = clap::arg!(foo: -'b' --hello); 91 assert_eq!(arg.get_id(), "foo"); 92 assert_eq!(arg.get_long(), Some("hello")); 93 assert_eq!(arg.get_short(), Some('b')); 94 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 95 assert_eq!(arg.get_num_args(), None); 96 assert!(!arg.is_required_set()); 97 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 98 99 let arg = clap::arg!(foo: -b --hello ...); 100 assert_eq!(arg.get_id(), "foo"); 101 assert_eq!(arg.get_long(), Some("hello")); 102 assert_eq!(arg.get_short(), Some('b')); 103 assert!(matches!(arg.get_action(), clap::ArgAction::Count)); 104 assert_eq!(arg.get_num_args(), None); 105 assert!(!arg.is_required_set()); 106 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 107 108 let arg = clap::arg!(foo: -b --hello "How to use it"); 109 assert_eq!(arg.get_id(), "foo"); 110 assert_eq!(arg.get_long(), Some("hello")); 111 assert_eq!(arg.get_short(), Some('b')); 112 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 113 assert_eq!(arg.get_num_args(), None); 114 assert!(!arg.is_required_set()); 115 assert_eq!( 116 arg.get_help().map(|s| s.to_string()), 117 Some("How to use it".to_owned()) 118 ); 119 } 120 121 #[test] short_help()122 fn short_help() { 123 let arg = clap::arg!(help: -b); 124 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 125 126 let mut cmd = clap::Command::new("cmd") 127 .disable_help_flag(true) 128 .arg(clap::arg!(help: -b).action(clap::ArgAction::Help)); 129 cmd.build(); 130 let arg = cmd 131 .get_arguments() 132 .find(|arg| arg.get_id() == "help") 133 .unwrap(); 134 assert!(matches!(arg.get_action(), clap::ArgAction::Help)); 135 } 136 137 #[test] long_help()138 fn long_help() { 139 let arg = clap::arg!(-'?' - -help); 140 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 141 142 let mut cmd = clap::Command::new("cmd") 143 .disable_help_flag(true) 144 .arg(clap::arg!(-'?' - -help).action(clap::ArgAction::Help)); 145 cmd.build(); 146 let arg = cmd 147 .get_arguments() 148 .find(|arg| arg.get_id() == "help") 149 .unwrap(); 150 assert!(matches!(arg.get_action(), clap::ArgAction::Help)); 151 } 152 153 #[test] short_version()154 fn short_version() { 155 let arg = clap::arg!(version: -b); 156 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 157 158 let mut cmd = clap::Command::new("cmd") 159 .disable_version_flag(true) 160 .version("1.0.0") 161 .arg(clap::arg!(version: -b).action(clap::ArgAction::Version)); 162 cmd.build(); 163 let arg = cmd 164 .get_arguments() 165 .find(|arg| arg.get_id() == "version") 166 .unwrap(); 167 assert!(matches!(arg.get_action(), clap::ArgAction::Version)); 168 } 169 170 #[test] long_version()171 fn long_version() { 172 let arg = clap::arg!(-'?' - -version); 173 assert!(matches!(arg.get_action(), clap::ArgAction::SetTrue)); 174 175 let mut cmd = clap::Command::new("cmd") 176 .disable_version_flag(true) 177 .version("1.0.0") 178 .arg(clap::arg!(-'?' - -version).action(clap::ArgAction::Version)); 179 cmd.build(); 180 let arg = cmd 181 .get_arguments() 182 .find(|arg| arg.get_id() == "version") 183 .unwrap(); 184 assert!(matches!(arg.get_action(), clap::ArgAction::Version)); 185 } 186 187 #[test] short_with_value()188 fn short_with_value() { 189 let arg = clap::arg!(foo: -b <NUM>); 190 assert_eq!(arg.get_id(), "foo"); 191 assert_eq!(arg.get_short(), Some('b')); 192 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 193 assert_eq!(arg.get_num_args(), None); 194 assert!(!arg.is_required_set()); 195 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 196 197 let arg = clap::arg!(foo: -'b' <NUM>); 198 assert_eq!(arg.get_id(), "foo"); 199 assert_eq!(arg.get_short(), Some('b')); 200 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 201 assert_eq!(arg.get_num_args(), None); 202 assert!(!arg.is_required_set()); 203 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 204 205 let arg = clap::arg!(foo: -b <NUM> ...); 206 assert_eq!(arg.get_id(), "foo"); 207 assert_eq!(arg.get_short(), Some('b')); 208 assert!(matches!(arg.get_action(), clap::ArgAction::Append)); 209 assert_eq!(arg.get_num_args(), None); 210 assert!(!arg.is_required_set()); 211 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 212 213 let arg = clap::arg!(foo: -b <NUM> "How to use it"); 214 assert_eq!(arg.get_id(), "foo"); 215 assert_eq!(arg.get_short(), Some('b')); 216 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 217 assert_eq!(arg.get_num_args(), None); 218 assert!(!arg.is_required_set()); 219 assert_eq!( 220 arg.get_help().map(|s| s.to_string()), 221 Some("How to use it".to_owned()) 222 ); 223 } 224 225 #[test] positional()226 fn positional() { 227 let arg = clap::arg!(<NUM>); 228 assert_eq!(arg.get_id(), "NUM"); 229 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 230 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 231 assert_eq!(arg.get_num_args(), None); 232 assert!(arg.is_required_set()); 233 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 234 235 let arg = clap::arg!([NUM]); 236 assert_eq!(arg.get_id(), "NUM"); 237 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 238 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 239 assert_eq!(arg.get_num_args(), None); 240 assert!(!arg.is_required_set()); 241 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 242 243 let arg = clap::arg!(<NUM>); 244 assert_eq!(arg.get_id(), "NUM"); 245 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 246 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 247 assert_eq!(arg.get_num_args(), None); 248 assert!(arg.is_required_set()); 249 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 250 251 let arg = clap::arg!(foo: <NUM>); 252 assert_eq!(arg.get_id(), "foo"); 253 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 254 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 255 assert_eq!(arg.get_num_args(), None); 256 assert!(arg.is_required_set()); 257 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 258 259 let arg = clap::arg!(<NUM> ...); 260 assert_eq!(arg.get_id(), "NUM"); 261 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 262 assert!(matches!(arg.get_action(), clap::ArgAction::Append)); 263 assert_eq!(arg.get_num_args(), Some((1..).into())); 264 assert!(arg.is_required_set()); 265 assert_eq!(arg.get_help().map(|s| s.to_string()), None); 266 267 let arg = clap::arg!(<NUM> "How to use it"); 268 assert_eq!(arg.get_id(), "NUM"); 269 assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); 270 assert!(matches!(arg.get_action(), clap::ArgAction::Set)); 271 assert_eq!(arg.get_num_args(), None); 272 assert!(arg.is_required_set()); 273 assert_eq!( 274 arg.get_help().map(|s| s.to_string()), 275 Some("How to use it".to_owned()) 276 ); 277 } 278 279 #[test] 280 #[cfg(all(feature = "help", featiure = "usage"))] optional_value()281 fn optional_value() { 282 let mut cmd = clap::Command::new("test").arg(clap::arg!(port: -p [NUM])); 283 284 let r = cmd.try_get_matches_from_mut(["test", "-p42"]); 285 assert!(r.is_ok(), "{}", r.unwrap_err()); 286 let m = r.unwrap(); 287 assert!(m.contains_id("port")); 288 assert_eq!(m.get_one::<String>("port").unwrap(), "42"); 289 290 let r = cmd.try_get_matches_from_mut(["test", "-p"]); 291 assert!(r.is_ok(), "{}", r.unwrap_err()); 292 let m = r.unwrap(); 293 assert!(m.contains_id("port")); 294 assert!(m.get_one::<String>("port").is_none()); 295 296 let r = cmd.try_get_matches_from_mut(["test", "-p", "24", "-p", "42"]); 297 assert!(r.is_ok(), "{}", r.unwrap_err()); 298 let m = r.unwrap(); 299 assert!(m.contains_id("port")); 300 assert_eq!(m.get_one::<String>("port").unwrap(), "42"); 301 302 let mut help = Vec::new(); 303 cmd.write_help(&mut help).unwrap(); 304 const HELP: &str = "\ 305 Usage: test [OPTIONS] 306 307 Options: 308 -p [<NUM>] 309 -h, --help Print help information 310 "; 311 snapbox::assert_eq(HELP, help); 312 } 313 } 314 315 mod arg_impl { 316 #[test] string_ident()317 fn string_ident() { 318 let expected = "one"; 319 let actual = clap::arg_impl! { @string one }; 320 assert_eq!(actual, expected); 321 } 322 323 #[test] string_literal()324 fn string_literal() { 325 let expected = "one"; 326 let actual = clap::arg_impl! { @string "one" }; 327 assert_eq!(actual, expected); 328 } 329 330 #[test] char_ident()331 fn char_ident() { 332 let expected = 'o'; 333 let actual = clap::arg_impl! { @char o }; 334 assert_eq!(actual, expected); 335 } 336 337 #[test] char_literal()338 fn char_literal() { 339 let expected = 'o'; 340 let actual = clap::arg_impl! { @char 'o' }; 341 assert_eq!(actual, expected); 342 } 343 344 #[test] 345 // allow double quoted dashed arg name in square brackets (e.g ["some-arg"]) arg_name_dashed()346 fn arg_name_dashed() { 347 let arg = clap::arg!(["some-arg"] "some arg"); 348 assert_eq!(arg, clap::Arg::new("some-arg").help("some arg")); 349 350 let m = clap::Command::new("flag") 351 .arg(arg) 352 .try_get_matches_from(vec!["", "some-val"]) 353 .unwrap(); 354 assert_eq!(m.get_one::<String>("some-arg").unwrap(), "some-val"); 355 } 356 357 #[test] 358 // allow double quoted dashed arg value in triangle brackets (e.g <"some-val">) 359 // test in combination with short argument name (e.g. -v) arg_value_dashed_with_short_arg()360 fn arg_value_dashed_with_short_arg() { 361 let arg = clap::arg!(-a <"some-val"> "some arg"); 362 assert_eq!( 363 arg, 364 clap::Arg::new("some-val") 365 .short('a') 366 .long("arg") 367 .value_name("some-val") 368 ); 369 370 let m = clap::Command::new("cmd") 371 .arg(arg) 372 .try_get_matches_from(vec!["", "-a", "val"]) 373 .unwrap(); 374 assert_eq!(m.get_one::<String>("some-val").unwrap(), "val"); 375 } 376 377 #[test] 378 // allow double quoted dashed arg value in triangle brackets (e.g <"some-val">) 379 // test in combination with long argument name (e.g. --value) arg_value_dashed_with_long_arg()380 fn arg_value_dashed_with_long_arg() { 381 let arg = clap::arg!(-a --arg <"some-val"> "some arg"); 382 assert_eq!( 383 arg, 384 clap::Arg::new("arg") 385 .short('a') 386 .long("arg") 387 .value_name("some-val") 388 ); 389 390 let m = clap::Command::new("cmd") 391 .arg(arg) 392 .try_get_matches_from(vec!["", "--arg", "some-val"]) 393 .unwrap(); 394 assert_eq!(m.get_one::<String>("arg").unwrap(), "some-val"); 395 } 396 } 397