1use clap::{arg, error::ErrorKind, Arg, ArgAction, ArgGroup, Command}; 2 3#[cfg(feature = "error-context")] 4use super::utils; 5 6#[test] 7fn flag_conflict() { 8 let result = Command::new("flag_conflict") 9 .arg(arg!(-f --flag "some flag").conflicts_with("other")) 10 .arg(arg!(-o --other "some flag")) 11 .try_get_matches_from(vec!["myprog", "-f", "-o"]); 12 assert!(result.is_err()); 13 let err = result.err().unwrap(); 14 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 15} 16 17#[test] 18fn flag_conflict_2() { 19 let result = Command::new("flag_conflict") 20 .arg(arg!(-f --flag "some flag").conflicts_with("other")) 21 .arg(arg!(-o --other "some flag")) 22 .try_get_matches_from(vec!["myprog", "-o", "-f"]); 23 assert!(result.is_err()); 24 let err = result.err().unwrap(); 25 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 26} 27 28#[test] 29fn flag_conflict_with_all() { 30 let result = Command::new("flag_conflict") 31 .arg(arg!(-f --flag "some flag").conflicts_with_all(["other"])) 32 .arg(arg!(-o --other "some flag")) 33 .try_get_matches_from(vec!["myprog", "-o", "-f"]); 34 assert!(result.is_err()); 35 let err = result.err().unwrap(); 36 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 37} 38 39#[test] 40fn exclusive_flag() { 41 let cmd = Command::new("flag_conflict") 42 .arg(arg!(-f --flag "some flag").exclusive(true)) 43 .arg(arg!(-o --other "some flag")); 44 let result = cmd.clone().try_get_matches_from(vec!["myprog", "-f"]); 45 assert!(result.is_ok(), "{}", result.unwrap_err()); 46 47 let result = cmd.clone().try_get_matches_from(vec!["myprog", "-o", "-f"]); 48 assert!(result.is_err()); 49 let err = result.err().unwrap(); 50 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 51} 52 53#[test] 54fn exclusive_option() { 55 let result = Command::new("flag_conflict") 56 .arg(arg!(-f --flag <VALUE> "some flag").exclusive(true)) 57 .arg(arg!(-o --other <VALUE> "some flag")) 58 .try_get_matches_from(vec!["myprog", "-o=val1", "-f=val2"]); 59 assert!(result.is_err()); 60 let err = result.err().unwrap(); 61 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 62} 63 64#[test] 65fn not_exclusive_with_defaults() { 66 let result = Command::new("flag_conflict") 67 .arg(arg!(-f --flag <VALUE> "some flag").exclusive(true)) 68 .arg( 69 arg!(-o --other <VALUE> "some flag") 70 .required(false) 71 .default_value("val1"), 72 ) 73 .try_get_matches_from(vec!["myprog", "-f=val2"]); 74 assert!(result.is_ok(), "{}", result.unwrap_err()); 75} 76 77#[test] 78fn not_exclusive_with_group() { 79 let cmd = Command::new("test") 80 .group(clap::ArgGroup::new("test").arg("foo")) 81 .arg( 82 clap::Arg::new("foo") 83 .long("foo") 84 .exclusive(true) 85 .action(clap::ArgAction::SetTrue), 86 ); 87 let result = cmd.try_get_matches_from(vec!["test", "--foo"]); 88 assert!(result.is_ok(), "{}", result.unwrap_err()); 89} 90 91#[test] 92fn default_doesnt_activate_exclusive() { 93 let result = Command::new("flag_conflict") 94 .arg( 95 arg!(-f --flag <VALUE> "some flag") 96 .exclusive(true) 97 .default_value("val2"), 98 ) 99 .arg(arg!(-o --other <VALUE> "some flag").default_value("val1")) 100 .try_get_matches_from(vec!["myprog"]); 101 assert!(result.is_ok(), "{}", result.unwrap_err()); 102} 103 104#[test] 105fn arg_conflicts_with_group() { 106 let mut cmd = Command::new("group_conflict") 107 .arg(arg!(-f --flag "some flag").conflicts_with("gr")) 108 .group(ArgGroup::new("gr").arg("some").arg("other")) 109 .arg(arg!(--some "some arg")) 110 .arg(arg!(--other "other arg")); 111 112 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]); 113 assert!(result.is_err()); 114 let err = result.err().unwrap(); 115 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 116 117 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]); 118 assert!(result.is_err()); 119 let err = result.err().unwrap(); 120 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 121 122 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]); 123 if let Err(err) = result { 124 panic!("{}", err); 125 } 126 127 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]); 128 if let Err(err) = result { 129 panic!("{}", err); 130 } 131 132 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--flag"]); 133 if let Err(err) = result { 134 panic!("{}", err); 135 } 136} 137 138#[test] 139fn arg_conflicts_with_group_with_multiple_sources() { 140 let mut cmd = clap::Command::new("group_conflict") 141 .arg(clap::arg!(-f --flag "some flag").conflicts_with("gr")) 142 .group(clap::ArgGroup::new("gr").multiple(true)) 143 .arg(clap::arg!(--some <name> "some arg").group("gr")) 144 .arg( 145 clap::arg!(--other <secs> "other arg") 146 .default_value("1000") 147 .group("gr"), 148 ); 149 150 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f"]); 151 if let Err(err) = result { 152 panic!("{}", err); 153 } 154 155 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some", "usb1"]); 156 if let Err(err) = result { 157 panic!("{}", err); 158 } 159 160 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some", "usb1", "--other", "40"]); 161 if let Err(err) = result { 162 panic!("{}", err); 163 } 164 165 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some", "usb1"]); 166 let err = result.err().unwrap(); 167 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 168} 169 170#[test] 171fn group_conflicts_with_arg() { 172 let mut cmd = Command::new("group_conflict") 173 .arg(arg!(-f --flag "some flag")) 174 .group( 175 ArgGroup::new("gr") 176 .arg("some") 177 .arg("other") 178 .conflicts_with("flag"), 179 ) 180 .arg(arg!(--some "some arg")) 181 .arg(arg!(--other "other arg")); 182 183 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]); 184 assert!(result.is_err()); 185 let err = result.err().unwrap(); 186 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 187 188 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]); 189 assert!(result.is_err()); 190 let err = result.err().unwrap(); 191 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 192 193 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]); 194 if let Err(err) = result { 195 panic!("{}", err); 196 } 197 198 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]); 199 if let Err(err) = result { 200 panic!("{}", err); 201 } 202 203 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--flag"]); 204 if let Err(err) = result { 205 panic!("{}", err); 206 } 207} 208 209#[test] 210fn arg_conflicts_with_required_group() { 211 let mut cmd = Command::new("group_conflict") 212 .arg(arg!(-f --flag "some flag").conflicts_with("gr")) 213 .group(ArgGroup::new("gr").required(true).arg("some").arg("other")) 214 .arg(arg!(--some "some arg")) 215 .arg(arg!(--other "other arg")); 216 217 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]); 218 assert!(result.is_err()); 219 let err = result.err().unwrap(); 220 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 221 222 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]); 223 assert!(result.is_err()); 224 let err = result.err().unwrap(); 225 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 226 227 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]); 228 if let Err(err) = result { 229 panic!("{}", err); 230 } 231 232 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]); 233 if let Err(err) = result { 234 panic!("{}", err); 235 } 236} 237 238#[test] 239fn arg_conflicts_with_group_with_required_memeber() { 240 let mut cmd = Command::new("group_conflict") 241 .arg(arg!(-f --flag "some flag").conflicts_with("gr")) 242 .group(ArgGroup::new("gr").arg("some").arg("other")) 243 .arg(arg!(--some "some arg").required(true)) 244 .arg(arg!(--other "other arg")); 245 246 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]); 247 assert!(result.is_err()); 248 let err = result.err().unwrap(); 249 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 250 251 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]); 252 assert!(result.is_err()); 253 let err = result.err().unwrap(); 254 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 255 256 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]); 257 if let Err(err) = result { 258 panic!("{}", err); 259 } 260 261 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--flag"]); 262 if let Err(err) = result { 263 panic!("{}", err); 264 } 265} 266 267#[test] 268fn required_group_conflicts_with_arg() { 269 let mut cmd = Command::new("group_conflict") 270 .arg(arg!(-f --flag "some flag")) 271 .group( 272 ArgGroup::new("gr") 273 .required(true) 274 .arg("some") 275 .arg("other") 276 .conflicts_with("flag"), 277 ) 278 .arg(arg!(--some "some arg")) 279 .arg(arg!(--other "other arg")); 280 281 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]); 282 assert!(result.is_err()); 283 let err = result.err().unwrap(); 284 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 285 286 let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]); 287 assert!(result.is_err()); 288 let err = result.err().unwrap(); 289 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 290 291 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]); 292 if let Err(err) = result { 293 panic!("{}", err); 294 } 295 296 let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]); 297 if let Err(err) = result { 298 panic!("{}", err); 299 } 300} 301 302#[test] 303fn get_arg_conflicts_with_group() { 304 let flag = arg!(--flag).conflicts_with("gr"); 305 let mut cmd = Command::new("group_conflict") 306 .arg(&flag) 307 .group(ArgGroup::new("gr").arg("some").arg("other")) 308 .arg(arg!(--some)) 309 .arg(arg!(--other)); 310 311 cmd.build(); 312 313 let result = cmd.get_arg_conflicts_with(&flag); 314 315 assert_eq!(result.len(), 2); 316 assert_eq!(result[0].get_id(), "some"); 317 assert_eq!(result[1].get_id(), "other"); 318} 319 320#[test] 321#[cfg(feature = "error-context")] 322fn conflict_output() { 323 static CONFLICT_ERR: &str = "\ 324error: the argument '--flag...' cannot be used with '-F' 325 326Usage: clap-test --flag... --long-option-2 <option2> <positional> <positional2> [positional3]... 327 328For more information, try '--help'. 329"; 330 331 utils::assert_output( 332 utils::complex_app(), 333 "clap-test val1 fa --flag --long-option-2 val2 -F", 334 CONFLICT_ERR, 335 true, 336 ); 337} 338 339#[test] 340#[cfg(feature = "error-context")] 341fn conflict_output_rev() { 342 static CONFLICT_ERR_REV: &str = "\ 343error: the argument '-F' cannot be used with '--flag...' 344 345Usage: clap-test -F --long-option-2 <option2> <positional> <positional2> [positional3]... 346 347For more information, try '--help'. 348"; 349 350 utils::assert_output( 351 utils::complex_app(), 352 "clap-test val1 fa -F --long-option-2 val2 --flag", 353 CONFLICT_ERR_REV, 354 true, 355 ); 356} 357 358#[test] 359#[cfg(feature = "error-context")] 360fn conflict_output_repeat() { 361 static ERR: &str = "\ 362error: the argument '-F' cannot be used multiple times 363 364Usage: clap-test [OPTIONS] [positional] [positional2] [positional3]... [COMMAND] 365 366For more information, try '--help'. 367"; 368 369 utils::assert_output(utils::complex_app(), "clap-test -F -F", ERR, true); 370} 371 372#[test] 373#[cfg(feature = "error-context")] 374fn conflict_output_with_required() { 375 static CONFLICT_ERR: &str = "\ 376error: the argument '--flag...' cannot be used with '-F' 377 378Usage: clap-test --flag... --long-option-2 <option2> <positional> <positional2> [positional3]... 379 380For more information, try '--help'. 381"; 382 383 utils::assert_output( 384 utils::complex_app(), 385 "clap-test val1 --flag --long-option-2 val2 -F", 386 CONFLICT_ERR, 387 true, 388 ); 389} 390 391#[test] 392#[cfg(feature = "error-context")] 393fn conflict_output_rev_with_required() { 394 static CONFLICT_ERR_REV: &str = "\ 395error: the argument '-F' cannot be used with '--flag...' 396 397Usage: clap-test -F --long-option-2 <option2> <positional> <positional2> [positional3]... 398 399For more information, try '--help'. 400"; 401 402 utils::assert_output( 403 utils::complex_app(), 404 "clap-test val1 -F --long-option-2 val2 --flag", 405 CONFLICT_ERR_REV, 406 true, 407 ); 408} 409 410#[test] 411#[cfg(feature = "error-context")] 412fn conflict_output_three_conflicting() { 413 static CONFLICT_ERR_THREE: &str = "\ 414error: the argument '--one' cannot be used with: 415 --two 416 --three 417 418Usage: three_conflicting_arguments --one 419 420For more information, try '--help'. 421"; 422 423 let cmd = Command::new("three_conflicting_arguments") 424 .arg( 425 Arg::new("one") 426 .long("one") 427 .action(ArgAction::SetTrue) 428 .conflicts_with_all(["two", "three"]), 429 ) 430 .arg( 431 Arg::new("two") 432 .long("two") 433 .action(ArgAction::SetTrue) 434 .conflicts_with_all(["one", "three"]), 435 ) 436 .arg( 437 Arg::new("three") 438 .long("three") 439 .action(ArgAction::SetTrue) 440 .conflicts_with_all(["one", "two"]), 441 ); 442 utils::assert_output( 443 cmd, 444 "three_conflicting_arguments --one --two --three", 445 CONFLICT_ERR_THREE, 446 true, 447 ); 448} 449 450#[test] 451#[cfg(feature = "error-context")] 452fn two_conflicting_arguments() { 453 let a = Command::new("two_conflicting_arguments") 454 .arg( 455 Arg::new("develop") 456 .long("develop") 457 .action(ArgAction::SetTrue) 458 .conflicts_with("production"), 459 ) 460 .arg( 461 Arg::new("production") 462 .long("production") 463 .action(ArgAction::SetTrue) 464 .conflicts_with("develop"), 465 ) 466 .try_get_matches_from(vec!["", "--develop", "--production"]); 467 468 assert!(a.is_err()); 469 let a = a.unwrap_err(); 470 assert!( 471 a.to_string() 472 .contains("the argument \'--develop\' cannot be used with \'--production\'"), 473 "{}", 474 a 475 ); 476} 477 478#[test] 479#[cfg(feature = "error-context")] 480fn three_conflicting_arguments() { 481 let a = Command::new("three_conflicting_arguments") 482 .arg( 483 Arg::new("one") 484 .long("one") 485 .action(ArgAction::SetTrue) 486 .conflicts_with_all(["two", "three"]), 487 ) 488 .arg( 489 Arg::new("two") 490 .long("two") 491 .action(ArgAction::SetTrue) 492 .conflicts_with_all(["one", "three"]), 493 ) 494 .arg( 495 Arg::new("three") 496 .long("three") 497 .action(ArgAction::SetTrue) 498 .conflicts_with_all(["one", "two"]), 499 ) 500 .try_get_matches_from(vec!["", "--one", "--two", "--three"]); 501 502 assert!(a.is_err()); 503 let a = a.unwrap_err(); 504 assert!( 505 a.to_string() 506 .contains("the argument \'--one\' cannot be used with:"), 507 "{}", 508 a 509 ); 510} 511 512#[cfg(debug_assertions)] 513#[test] 514#[should_panic = "Argument 'config' cannot conflict with itself"] 515fn self_conflicting_arg() { 516 let _ = Command::new("prog") 517 .arg(Arg::new("config").long("config").conflicts_with("config")) 518 .try_get_matches_from(vec!["", "--config"]); 519} 520 521#[cfg(debug_assertions)] 522#[test] 523#[should_panic = "Argument or group 'extra' specified in 'conflicts_with*' for 'config' does not exist"] 524fn conflicts_with_invalid_arg() { 525 let _ = Command::new("prog") 526 .arg(Arg::new("config").long("config").conflicts_with("extra")) 527 .try_get_matches_from(vec!["", "--config"]); 528} 529 530#[test] 531fn conflict_with_unused_default() { 532 let result = Command::new("conflict") 533 .arg(arg!(-o --opt <opt> "some opt").default_value("default")) 534 .arg( 535 arg!(-f --flag "some flag") 536 .conflicts_with("opt") 537 .action(ArgAction::SetTrue), 538 ) 539 .try_get_matches_from(vec!["myprog", "-f"]); 540 541 assert!(result.is_ok(), "{}", result.unwrap_err()); 542 let m = result.unwrap(); 543 544 assert_eq!( 545 m.get_one::<String>("opt").map(|v| v.as_str()), 546 Some("default") 547 ); 548 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 549} 550 551#[test] 552fn conflicts_with_alongside_default() { 553 let result = Command::new("conflict") 554 .arg( 555 arg!(-o --opt <opt> "some opt") 556 .default_value("default") 557 .conflicts_with("flag"), 558 ) 559 .arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue)) 560 .try_get_matches_from(vec!["myprog", "-f"]); 561 562 assert!( 563 result.is_ok(), 564 "conflicts_with should ignore default_value: {:?}", 565 result.unwrap_err() 566 ); 567 let m = result.unwrap(); 568 569 assert_eq!( 570 m.get_one::<String>("opt").map(|v| v.as_str()), 571 Some("default") 572 ); 573 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 574} 575 576#[test] 577fn group_in_conflicts_with() { 578 let result = Command::new("conflict") 579 .arg( 580 Arg::new("opt") 581 .long("opt") 582 .default_value("default") 583 .group("one"), 584 ) 585 .arg( 586 Arg::new("flag") 587 .long("flag") 588 .conflicts_with("one") 589 .action(ArgAction::SetTrue), 590 ) 591 .try_get_matches_from(vec!["myprog", "--flag"]); 592 593 assert!( 594 result.is_ok(), 595 "conflicts_with on an arg group should ignore default_value: {:?}", 596 result.unwrap_err() 597 ); 598 let m = result.unwrap(); 599 600 assert_eq!( 601 m.get_one::<String>("opt").map(|v| v.as_str()), 602 Some("default") 603 ); 604 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 605} 606 607#[test] 608fn group_conflicts_with_default_value() { 609 let result = Command::new("conflict") 610 .arg( 611 Arg::new("opt") 612 .long("opt") 613 .default_value("default") 614 .group("one"), 615 ) 616 .arg( 617 Arg::new("flag") 618 .long("flag") 619 .group("one") 620 .action(ArgAction::SetTrue), 621 ) 622 .try_get_matches_from(vec!["myprog", "--flag"]); 623 624 assert!( 625 result.is_ok(), 626 "arg group count should ignore default_value: {:?}", 627 result.unwrap_err() 628 ); 629 let m = result.unwrap(); 630 631 assert_eq!( 632 m.get_one::<String>("opt").map(|v| v.as_str()), 633 Some("default") 634 ); 635 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 636} 637 638#[test] 639fn group_conflicts_with_default_arg() { 640 let result = Command::new("conflict") 641 .arg(Arg::new("opt").long("opt").default_value("default")) 642 .arg( 643 Arg::new("flag") 644 .long("flag") 645 .group("one") 646 .action(ArgAction::SetTrue), 647 ) 648 .group(ArgGroup::new("one").conflicts_with("opt")) 649 .try_get_matches_from(vec!["myprog", "--flag"]); 650 651 assert!( 652 result.is_ok(), 653 "arg group conflicts_with should ignore default_value: {:?}", 654 result.unwrap_err() 655 ); 656 let m = result.unwrap(); 657 658 assert_eq!( 659 m.get_one::<String>("opt").map(|v| v.as_str()), 660 Some("default") 661 ); 662 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 663} 664 665#[test] 666fn exclusive_with_required() { 667 let cmd = Command::new("bug") 668 .arg( 669 Arg::new("test") 670 .long("test") 671 .action(ArgAction::SetTrue) 672 .exclusive(true), 673 ) 674 .arg(Arg::new("input").action(ArgAction::Set).required(true)); 675 676 cmd.clone() 677 .try_get_matches_from(["bug", "--test", "required"]) 678 .unwrap_err(); 679 680 cmd.clone() 681 .try_get_matches_from(["bug", "required"]) 682 .unwrap(); 683 684 cmd.clone().try_get_matches_from(["bug", "--test"]).unwrap(); 685} 686 687#[test] 688fn args_negate_subcommands_one_level() { 689 let res = Command::new("disablehelp") 690 .args_conflicts_with_subcommands(true) 691 .subcommand_negates_reqs(true) 692 .arg(arg!(<arg1> "some arg")) 693 .arg(arg!(<arg2> "some arg")) 694 .subcommand( 695 Command::new("sub1").subcommand(Command::new("sub2").subcommand(Command::new("sub3"))), 696 ) 697 .try_get_matches_from(vec!["", "pickles", "sub1"]); 698 assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind()); 699 let m = res.unwrap(); 700 assert_eq!( 701 m.get_one::<String>("arg2").map(|v| v.as_str()), 702 Some("sub1") 703 ); 704} 705 706#[test] 707fn args_negate_subcommands_two_levels() { 708 let res = Command::new("disablehelp") 709 .args_conflicts_with_subcommands(true) 710 .subcommand_negates_reqs(true) 711 .arg(arg!(<arg1> "some arg")) 712 .arg(arg!(<arg2> "some arg")) 713 .subcommand( 714 Command::new("sub1") 715 .args_conflicts_with_subcommands(true) 716 .subcommand_negates_reqs(true) 717 .arg(arg!(<arg> "some")) 718 .arg(arg!(<arg2> "some")) 719 .subcommand(Command::new("sub2").subcommand(Command::new("sub3"))), 720 ) 721 .try_get_matches_from(vec!["", "sub1", "arg", "sub2"]); 722 assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind()); 723 let m = res.unwrap(); 724 assert_eq!( 725 m.subcommand_matches("sub1") 726 .unwrap() 727 .get_one::<String>("arg2") 728 .map(|v| v.as_str()), 729 Some("sub2") 730 ); 731} 732 733#[test] 734#[cfg(feature = "error-context")] 735fn subcommand_conflict_error_message() { 736 static CONFLICT_ERR: &str = "\ 737error: unexpected argument 'sub1' found 738 739Usage: test [OPTIONS] 740 test <COMMAND> 741 742For more information, try '--help'. 743"; 744 745 let cmd = Command::new("test") 746 .args_conflicts_with_subcommands(true) 747 .arg(arg!(-p --place <"place id"> "Place ID to open")) 748 .subcommand( 749 Command::new("sub1").subcommand(Command::new("sub2").subcommand(Command::new("sub3"))), 750 ); 751 752 utils::assert_output(cmd, "test --place id sub1", CONFLICT_ERR, true); 753} 754 755#[test] 756fn subcommand_conflict_negates_required() { 757 let cmd = Command::new("test") 758 .args_conflicts_with_subcommands(true) 759 .subcommand(Command::new("config")) 760 .arg(arg!(-p --place <"place id"> "Place ID to open").required(true)); 761 762 let result = cmd.try_get_matches_from(["test", "config"]); 763 assert!( 764 result.is_ok(), 765 "args_conflicts_with_subcommands should ignore required: {}", 766 result.unwrap_err() 767 ); 768 let m = result.unwrap(); 769 assert_eq!(m.subcommand_name().unwrap(), "config"); 770} 771