1use clap::{builder::PossibleValue, error::ErrorKind, Arg, ArgAction, Command}; 2 3#[cfg(feature = "error-context")] 4use super::utils; 5 6#[test] 7fn possible_values_of_positional() { 8 let m = Command::new("possible_values") 9 .arg(Arg::new("positional").index(1).value_parser(["test123"])) 10 .try_get_matches_from(vec!["myprog", "test123"]); 11 12 assert!(m.is_ok(), "{}", m.unwrap_err()); 13 let m = m.unwrap(); 14 15 assert!(m.contains_id("positional")); 16 assert_eq!( 17 m.get_one::<String>("positional").map(|v| v.as_str()), 18 Some("test123") 19 ); 20} 21 22#[test] 23fn possible_value_arg_value() { 24 let m = Command::new("possible_values") 25 .arg( 26 Arg::new("arg_value") 27 .index(1) 28 .value_parser([PossibleValue::new("test123") 29 .hide(false) 30 .help("It's just a test")]), 31 ) 32 .try_get_matches_from(vec!["myprog", "test123"]); 33 34 assert!(m.is_ok(), "{}", m.unwrap_err()); 35 let m = m.unwrap(); 36 37 assert!(m.contains_id("arg_value")); 38 assert_eq!( 39 m.get_one::<String>("arg_value").map(|v| v.as_str()), 40 Some("test123") 41 ); 42} 43 44#[test] 45fn possible_values_of_positional_fail() { 46 let m = Command::new("possible_values") 47 .arg(Arg::new("positional").index(1).value_parser(["test123"])) 48 .try_get_matches_from(vec!["myprog", "notest"]); 49 50 assert!(m.is_err()); 51 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 52} 53 54#[test] 55fn possible_values_of_positional_multiple() { 56 let m = Command::new("possible_values") 57 .arg( 58 Arg::new("positional") 59 .index(1) 60 .action(ArgAction::Set) 61 .value_parser(["test123", "test321"]) 62 .num_args(1..), 63 ) 64 .try_get_matches_from(vec!["myprog", "test123", "test321"]); 65 66 assert!(m.is_ok(), "{}", m.unwrap_err()); 67 let m = m.unwrap(); 68 69 assert!(m.contains_id("positional")); 70 assert_eq!( 71 m.get_many::<String>("positional") 72 .unwrap() 73 .map(|v| v.as_str()) 74 .collect::<Vec<_>>(), 75 vec!["test123", "test321"] 76 ); 77} 78 79#[test] 80fn possible_values_of_positional_multiple_fail() { 81 let m = Command::new("possible_values") 82 .arg( 83 Arg::new("positional") 84 .index(1) 85 .action(ArgAction::Set) 86 .value_parser(["test123", "test321"]) 87 .num_args(1..), 88 ) 89 .try_get_matches_from(vec!["myprog", "test123", "notest"]); 90 91 assert!(m.is_err()); 92 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 93} 94 95#[test] 96fn possible_values_of_option() { 97 let m = Command::new("possible_values") 98 .arg( 99 Arg::new("option") 100 .short('o') 101 .long("option") 102 .action(ArgAction::Set) 103 .value_parser(["test123"]), 104 ) 105 .try_get_matches_from(vec!["myprog", "--option", "test123"]); 106 107 assert!(m.is_ok(), "{}", m.unwrap_err()); 108 let m = m.unwrap(); 109 110 assert!(m.contains_id("option")); 111 assert_eq!( 112 m.get_one::<String>("option").map(|v| v.as_str()), 113 Some("test123") 114 ); 115} 116 117#[test] 118fn possible_values_of_option_fail() { 119 let m = Command::new("possible_values") 120 .arg( 121 Arg::new("option") 122 .short('o') 123 .long("option") 124 .action(ArgAction::Set) 125 .value_parser(["test123"]), 126 ) 127 .try_get_matches_from(vec!["myprog", "--option", "notest"]); 128 129 assert!(m.is_err()); 130 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 131} 132 133#[test] 134fn possible_values_of_option_multiple() { 135 let m = Command::new("possible_values") 136 .arg( 137 Arg::new("option") 138 .short('o') 139 .long("option") 140 .action(ArgAction::Set) 141 .value_parser(["test123", "test321"]) 142 .action(ArgAction::Append), 143 ) 144 .try_get_matches_from(vec!["", "--option", "test123", "--option", "test321"]); 145 146 assert!(m.is_ok(), "{}", m.unwrap_err()); 147 let m = m.unwrap(); 148 149 assert!(m.contains_id("option")); 150 assert_eq!( 151 m.get_many::<String>("option") 152 .unwrap() 153 .map(|v| v.as_str()) 154 .collect::<Vec<_>>(), 155 vec!["test123", "test321"] 156 ); 157} 158 159#[test] 160fn possible_values_of_option_multiple_fail() { 161 let m = Command::new("possible_values") 162 .arg( 163 Arg::new("option") 164 .short('o') 165 .long("option") 166 .action(ArgAction::Set) 167 .value_parser(["test123", "test321"]) 168 .action(ArgAction::Append), 169 ) 170 .try_get_matches_from(vec!["", "--option", "test123", "--option", "notest"]); 171 172 assert!(m.is_err()); 173 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 174} 175 176#[test] 177#[cfg(feature = "error-context")] 178fn possible_values_output() { 179 #[cfg(feature = "suggestions")] 180 static PV_ERROR: &str = "\ 181error: invalid value 'slo' for '-O <option>' 182 [possible values: slow, fast, \"ludicrous speed\"] 183 184 note: value 'slow' exists 185 186For more information, try '--help'. 187"; 188 189 #[cfg(not(feature = "suggestions"))] 190 static PV_ERROR: &str = "\ 191error: invalid value 'slo' for '-O <option>' 192 [possible values: slow, fast, \"ludicrous speed\"] 193 194For more information, try '--help'. 195"; 196 197 utils::assert_output( 198 Command::new("test").arg( 199 Arg::new("option") 200 .short('O') 201 .action(ArgAction::Set) 202 .value_parser(["slow", "fast", "ludicrous speed"]), 203 ), 204 "clap-test -O slo", 205 PV_ERROR, 206 true, 207 ); 208} 209 210#[test] 211#[cfg(feature = "error-context")] 212fn possible_values_alias_output() { 213 #[cfg(feature = "suggestions")] 214 static PV_ERROR: &str = "\ 215error: invalid value 'slo' for '-O <option>' 216 [possible values: slow, fast, \"ludicrous speed\"] 217 218 note: value 'slow' exists 219 220For more information, try '--help'. 221"; 222 223 #[cfg(not(feature = "suggestions"))] 224 static PV_ERROR: &str = "\ 225error: invalid value 'slo' for '-O <option>' 226 [possible values: slow, fast, \"ludicrous speed\"] 227 228For more information, try '--help'. 229"; 230 231 utils::assert_output( 232 Command::new("test").arg( 233 Arg::new("option") 234 .short('O') 235 .action(ArgAction::Set) 236 .value_parser([ 237 "slow".into(), 238 PossibleValue::new("fast").alias("fost"), 239 PossibleValue::new("ludicrous speed").aliases(["ls", "lcs"]), 240 ]), 241 ), 242 "clap-test -O slo", 243 PV_ERROR, 244 true, 245 ); 246} 247 248#[test] 249#[cfg(feature = "error-context")] 250fn possible_values_hidden_output() { 251 #[cfg(feature = "suggestions")] 252 static PV_ERROR: &str = "\ 253error: invalid value 'slo' for '-O <option>' 254 [possible values: slow, fast, \"ludicrous speed\"] 255 256 note: value 'slow' exists 257 258For more information, try '--help'. 259"; 260 261 #[cfg(not(feature = "suggestions"))] 262 static PV_ERROR: &str = "\ 263error: invalid value 'slo' for '-O <option>' 264 [possible values: slow, fast, \"ludicrous speed\"] 265 266For more information, try '--help'. 267"; 268 269 utils::assert_output( 270 Command::new("test").arg( 271 Arg::new("option") 272 .short('O') 273 .action(ArgAction::Set) 274 .value_parser([ 275 "slow".into(), 276 "fast".into(), 277 PossibleValue::new("ludicrous speed"), 278 PossibleValue::new("forbidden speed").hide(true), 279 ]), 280 ), 281 "clap-test -O slo", 282 PV_ERROR, 283 true, 284 ); 285} 286 287#[test] 288#[cfg(feature = "error-context")] 289fn escaped_possible_values_output() { 290 #[cfg(feature = "suggestions")] 291 static PV_ERROR_ESCAPED: &str = "\ 292error: invalid value 'ludicrous' for '-O <option>' 293 [possible values: slow, fast, \"ludicrous speed\"] 294 295 note: value 'ludicrous speed' exists 296 297For more information, try '--help'. 298"; 299 300 #[cfg(not(feature = "suggestions"))] 301 static PV_ERROR_ESCAPED: &str = "\ 302error: invalid value 'ludicrous' for '-O <option>' 303 [possible values: slow, fast, \"ludicrous speed\"] 304 305For more information, try '--help'. 306"; 307 308 utils::assert_output( 309 Command::new("test").arg( 310 Arg::new("option") 311 .short('O') 312 .action(ArgAction::Set) 313 .value_parser(["slow", "fast", "ludicrous speed"]), 314 ), 315 "clap-test -O ludicrous", 316 PV_ERROR_ESCAPED, 317 true, 318 ); 319} 320 321#[test] 322#[cfg(feature = "error-context")] 323fn missing_possible_value_error() { 324 static MISSING_PV_ERROR: &str = "\ 325error: a value is required for '-O <option>' but none was supplied 326 [possible values: slow, fast, \"ludicrous speed\"] 327 328For more information, try '--help'. 329"; 330 331 utils::assert_output( 332 Command::new("test").arg( 333 Arg::new("option") 334 .short('O') 335 .action(ArgAction::Set) 336 .value_parser([ 337 "slow".into(), 338 PossibleValue::new("fast").alias("fost"), 339 PossibleValue::new("ludicrous speed"), 340 PossibleValue::new("forbidden speed").hide(true), 341 ]), 342 ), 343 "clap-test -O", 344 MISSING_PV_ERROR, 345 true, 346 ); 347} 348 349#[test] 350fn alias() { 351 let m = Command::new("pv") 352 .arg( 353 Arg::new("option") 354 .short('o') 355 .long("option") 356 .action(ArgAction::Set) 357 .value_parser([PossibleValue::new("test123").alias("123"), "test321".into()]) 358 .ignore_case(true), 359 ) 360 .try_get_matches_from(vec!["pv", "--option", "123"]); 361 362 assert!(m.is_ok(), "{}", m.unwrap_err()); 363 assert!(m 364 .unwrap() 365 .get_one::<String>("option") 366 .map(|v| v.as_str()) 367 .unwrap() 368 .eq("123")); 369} 370 371#[test] 372fn aliases() { 373 let m = Command::new("pv") 374 .arg( 375 Arg::new("option") 376 .short('o') 377 .long("option") 378 .action(ArgAction::Set) 379 .value_parser([ 380 PossibleValue::new("test123").aliases(["1", "2", "3"]), 381 "test321".into(), 382 ]) 383 .ignore_case(true), 384 ) 385 .try_get_matches_from(vec!["pv", "--option", "2"]); 386 387 assert!(m.is_ok(), "{}", m.unwrap_err()); 388 assert!(m 389 .unwrap() 390 .get_one::<String>("option") 391 .map(|v| v.as_str()) 392 .unwrap() 393 .eq("2")); 394} 395 396#[test] 397fn ignore_case() { 398 let m = Command::new("pv") 399 .arg( 400 Arg::new("option") 401 .short('o') 402 .long("option") 403 .action(ArgAction::Set) 404 .value_parser(["test123", "test321"]) 405 .ignore_case(true), 406 ) 407 .try_get_matches_from(vec!["pv", "--option", "TeSt123"]); 408 409 assert!(m.is_ok(), "{}", m.unwrap_err()); 410 assert!(m 411 .unwrap() 412 .get_one::<String>("option") 413 .map(|v| v.as_str()) 414 .unwrap() 415 .eq_ignore_ascii_case("test123")); 416} 417 418#[test] 419fn ignore_case_fail() { 420 let m = Command::new("pv") 421 .arg( 422 Arg::new("option") 423 .short('o') 424 .long("option") 425 .action(ArgAction::Set) 426 .value_parser(["test123", "test321"]), 427 ) 428 .try_get_matches_from(vec!["pv", "--option", "TeSt123"]); 429 430 assert!(m.is_err()); 431 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 432} 433 434#[test] 435fn ignore_case_multiple() { 436 let m = Command::new("pv") 437 .arg( 438 Arg::new("option") 439 .short('o') 440 .long("option") 441 .action(ArgAction::Set) 442 .value_parser(["test123", "test321"]) 443 .num_args(1..) 444 .ignore_case(true), 445 ) 446 .try_get_matches_from(vec!["pv", "--option", "TeSt123", "teST123", "tESt321"]); 447 448 assert!(m.is_ok(), "{}", m.unwrap_err()); 449 assert_eq!( 450 m.unwrap() 451 .get_many::<String>("option") 452 .unwrap() 453 .map(|v| v.as_str()) 454 .collect::<Vec<_>>(), 455 ["TeSt123", "teST123", "tESt321"] 456 ); 457} 458 459#[test] 460fn ignore_case_multiple_fail() { 461 let m = Command::new("pv") 462 .arg( 463 Arg::new("option") 464 .short('o') 465 .long("option") 466 .action(ArgAction::Set) 467 .value_parser(["test123", "test321"]) 468 .num_args(1..), 469 ) 470 .try_get_matches_from(vec!["pv", "--option", "test123", "teST123", "test321"]); 471 472 assert!(m.is_err()); 473 assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue); 474} 475