1use clap::{error::ErrorKind, Arg, ArgAction, Command};
2
3static HELP: &str = "\
4Usage: prog [OPTIONS]
5
6Options:
7  -a
8  -b
9  -c
10  -h, --help  Print help
11";
12
13fn cmd() -> Command {
14    Command::new("prog")
15        .arg(
16            Arg::new("a")
17                .short('a')
18                .action(ArgAction::SetTrue)
19                .required_unless_present_any(["b", "c"])
20                .conflicts_with_all(["b", "c"]),
21        )
22        .arg(
23            Arg::new("b")
24                .short('b')
25                .action(ArgAction::SetTrue)
26                .required_unless_present("a")
27                .requires("c"),
28        )
29        .arg(
30            Arg::new("c")
31                .short('c')
32                .action(ArgAction::SetTrue)
33                .required_unless_present("a")
34                .requires("b"),
35        )
36}
37
38#[test]
39fn valid_cases() {
40    let res = cmd().try_get_matches_from(vec!["", "-a"]);
41    assert!(res.is_ok(), "{}", res.unwrap_err());
42    let res = cmd().clone().try_get_matches_from(vec!["", "-b", "-c"]);
43    assert!(res.is_ok(), "{}", res.unwrap_err());
44    let res = cmd().try_get_matches_from(vec!["", "-c", "-b"]);
45    assert!(res.is_ok(), "{}", res.unwrap_err());
46}
47
48#[test]
49fn help_text() {
50    let res = cmd().try_get_matches_from(vec!["prog", "--help"]);
51    assert!(res.is_err());
52    let err = res.unwrap_err();
53    assert_eq!(err.kind(), ErrorKind::DisplayHelp);
54    println!("{}", err);
55    assert_eq!(err.to_string(), HELP);
56}
57
58#[test]
59#[cfg(feature = "error-context")]
60fn no_duplicate_error() {
61    static ONLY_B_ERROR: &str = "\
62error: the following required arguments were not provided:
63  -c
64
65Usage: prog -b -c
66
67For more information, try '--help'.
68";
69
70    let res = cmd().try_get_matches_from(vec!["", "-b"]);
71    assert!(res.is_err());
72    let err = res.unwrap_err();
73    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
74    assert_eq!(err.to_string(), ONLY_B_ERROR);
75
76    static ONLY_C_ERROR: &str = "\
77error: the following required arguments were not provided:
78  -b
79
80Usage: prog -c -b
81
82For more information, try '--help'.
83";
84
85    let res = cmd().try_get_matches_from(vec!["", "-c"]);
86    assert!(res.is_err());
87    let err = res.unwrap_err();
88    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
89    assert_eq!(err.to_string(), ONLY_C_ERROR);
90}
91