1use clap::Parser;
2
3use crate::utils::assert_output;
4
5#[test]
6fn test_safely_nest_parser() {
7    #[derive(Parser, Debug, PartialEq)]
8    struct Opt {
9        #[command(flatten)]
10        foo: Foo,
11    }
12
13    #[derive(Parser, Debug, PartialEq)]
14    struct Foo {
15        #[arg(long)]
16        foo: bool,
17    }
18
19    assert_eq!(
20        Opt {
21            foo: Foo { foo: true }
22        },
23        Opt::try_parse_from(["test", "--foo"]).unwrap()
24    );
25}
26
27#[test]
28fn implicit_struct_group() {
29    #[derive(Parser, Debug)]
30    struct Opt {
31        #[arg(short, long, requires = "Source")]
32        add: bool,
33
34        #[command(flatten)]
35        source: Source,
36    }
37
38    #[derive(clap::Args, Debug)]
39    struct Source {
40        crates: Vec<String>,
41        #[arg(long)]
42        path: Option<std::path::PathBuf>,
43        #[arg(long)]
44        git: Option<String>,
45    }
46
47    const OUTPUT: &str = "\
48error: the following required arguments were not provided:
49  <CRATES|--path <PATH>|--git <GIT>>
50
51Usage: prog --add <CRATES|--path <PATH>|--git <GIT>>
52
53For more information, try '--help'.
54";
55    assert_output::<Opt>("prog --add", OUTPUT, true);
56
57    use clap::Args;
58    assert_eq!(Source::group_id(), Some(clap::Id::from("Source")));
59    assert_eq!(Opt::group_id(), Some(clap::Id::from("Opt")));
60}
61
62#[test]
63fn skip_group_avoids_duplicate_ids() {
64    #[derive(Parser, Debug)]
65    #[group(skip)]
66    struct Opt {
67        #[command(flatten)]
68        first: Compose<Empty, Empty>,
69        #[command(flatten)]
70        second: Compose<Empty, Empty>,
71    }
72
73    #[derive(clap::Args, Debug)]
74    #[group(skip)]
75    pub struct Compose<L: clap::Args, R: clap::Args> {
76        #[command(flatten)]
77        pub left: L,
78        #[command(flatten)]
79        pub right: R,
80    }
81
82    #[derive(clap::Args, Clone, Copy, Debug)]
83    #[group(skip)]
84    pub struct Empty;
85
86    use clap::CommandFactory;
87    Opt::command().debug_assert();
88
89    use clap::Args;
90    assert_eq!(Empty::group_id(), None);
91    assert_eq!(Compose::<Empty, Empty>::group_id(), None);
92    assert_eq!(Opt::group_id(), None);
93}
94
95#[test]
96#[should_panic = "\
97Command clap: Argument group name must be unique
98
99\t'Compose' is already in use (note: `Args` implicitly creates `ArgGroup`s; disable with `#[group(skip)]`"]
100fn helpful_panic_on_duplicate_groups() {
101    #[derive(Parser, Debug)]
102    struct Opt {
103        #[command(flatten)]
104        first: Compose<Empty, Empty>,
105        #[command(flatten)]
106        second: Compose<Empty, Empty>,
107    }
108
109    #[derive(clap::Args, Debug)]
110    pub struct Compose<L: clap::Args, R: clap::Args> {
111        #[command(flatten)]
112        pub left: L,
113        #[command(flatten)]
114        pub right: R,
115    }
116
117    #[derive(clap::Args, Clone, Copy, Debug)]
118    pub struct Empty;
119
120    use clap::CommandFactory;
121    Opt::command().debug_assert();
122}
123