1 use clap::{error::ErrorKind, ArgAction, Command};
2
3 use crate::utils;
4
common() -> Command5 fn common() -> Command {
6 Command::new("foo").help_template(utils::FULL_TEMPLATE)
7 }
8
with_version() -> Command9 fn with_version() -> Command {
10 common().version("3.0")
11 }
12
with_long_version() -> Command13 fn with_long_version() -> Command {
14 common().long_version("3.0 (abcdefg)")
15 }
16
with_both() -> Command17 fn with_both() -> Command {
18 common().version("3.0").long_version("3.0 (abcdefg)")
19 }
20
with_subcommand() -> Command21 fn with_subcommand() -> Command {
22 with_version().subcommand(Command::new("bar").subcommand(Command::new("baz")))
23 }
24
25 #[test]
version_short_flag_no_version()26 fn version_short_flag_no_version() {
27 let res = common().try_get_matches_from("foo -V".split(' '));
28
29 assert!(res.is_err());
30 let err = res.unwrap_err();
31 assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
32 }
33
34 #[test]
version_long_flag_no_version()35 fn version_long_flag_no_version() {
36 let res = common().try_get_matches_from("foo --version".split(' '));
37
38 assert!(res.is_err());
39 let err = res.unwrap_err();
40 assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
41 }
42
43 #[test]
version_short_flag_with_version()44 fn version_short_flag_with_version() {
45 let res = with_version().try_get_matches_from("foo -V".split(' '));
46
47 assert!(res.is_err());
48 let err = res.unwrap_err();
49 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
50 assert_eq!(err.to_string(), "foo 3.0\n");
51 }
52
53 #[test]
version_long_flag_with_version()54 fn version_long_flag_with_version() {
55 let res = with_version().try_get_matches_from("foo --version".split(' '));
56
57 assert!(res.is_err());
58 let err = res.unwrap_err();
59 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
60 assert_eq!(err.to_string(), "foo 3.0\n");
61 }
62
63 #[test]
version_short_flag_with_long_version()64 fn version_short_flag_with_long_version() {
65 let res = with_long_version().try_get_matches_from("foo -V".split(' '));
66
67 assert!(res.is_err());
68 let err = res.unwrap_err();
69 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
70 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n");
71 }
72
73 #[test]
version_long_flag_with_long_version()74 fn version_long_flag_with_long_version() {
75 let res = with_long_version().try_get_matches_from("foo --version".split(' '));
76
77 assert!(res.is_err());
78 let err = res.unwrap_err();
79 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
80 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n");
81 }
82
83 #[test]
version_short_flag_with_both()84 fn version_short_flag_with_both() {
85 let res = with_both().try_get_matches_from("foo -V".split(' '));
86
87 assert!(res.is_err());
88 let err = res.unwrap_err();
89 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
90 assert_eq!(err.to_string(), "foo 3.0\n");
91 }
92
93 #[test]
version_long_flag_with_both()94 fn version_long_flag_with_both() {
95 let res = with_both().try_get_matches_from("foo --version".split(' '));
96
97 assert!(res.is_err());
98 let err = res.unwrap_err();
99 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
100 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n");
101 }
102
103 #[test]
help_short_flag_no_version()104 fn help_short_flag_no_version() {
105 static EXPECTED: &str = "\
106 foo
107
108 Usage: foo
109
110 Options:
111 -h, --help Print help
112 ";
113 let cmd = common();
114 utils::assert_output(cmd, "foo -h", EXPECTED, false);
115 }
116
117 #[test]
help_long_flag_no_version()118 fn help_long_flag_no_version() {
119 static EXPECTED: &str = "\
120 foo
121
122 Usage: foo
123
124 Options:
125 -h, --help Print help
126 ";
127 let cmd = common();
128 utils::assert_output(cmd, "foo --help", EXPECTED, false);
129 }
130
131 #[test]
help_short_flag_with_version()132 fn help_short_flag_with_version() {
133 static EXPECTED: &str = "\
134 foo 3.0
135
136 Usage: foo
137
138 Options:
139 -h, --help Print help
140 -V, --version Print version
141 ";
142 let cmd = with_version();
143 utils::assert_output(cmd, "foo -h", EXPECTED, false);
144 }
145
146 #[test]
help_long_flag_with_version()147 fn help_long_flag_with_version() {
148 static EXPECTED: &str = "\
149 foo 3.0
150
151 Usage: foo
152
153 Options:
154 -h, --help Print help
155 -V, --version Print version
156 ";
157 let cmd = with_version();
158 utils::assert_output(cmd, "foo --help", EXPECTED, false);
159 }
160
161 #[test]
help_short_flag_with_long_version()162 fn help_short_flag_with_long_version() {
163 static EXPECTED: &str = "\
164 foo 3.0 (abcdefg)
165
166 Usage: foo
167
168 Options:
169 -h, --help Print help
170 -V, --version Print version
171 ";
172 let cmd = with_long_version();
173 utils::assert_output(cmd, "foo -h", EXPECTED, false);
174 }
175
176 #[test]
help_long_flag_with_long_version()177 fn help_long_flag_with_long_version() {
178 static EXPECTED: &str = "\
179 foo 3.0 (abcdefg)
180
181 Usage: foo
182
183 Options:
184 -h, --help Print help
185 -V, --version Print version
186 ";
187 let cmd = with_long_version();
188 utils::assert_output(cmd, "foo --help", EXPECTED, false);
189 }
190
191 #[test]
help_short_flag_with_both()192 fn help_short_flag_with_both() {
193 static EXPECTED: &str = "\
194 foo 3.0
195
196 Usage: foo
197
198 Options:
199 -h, --help Print help
200 -V, --version Print version
201 ";
202 let cmd = with_both();
203 utils::assert_output(cmd, "foo -h", EXPECTED, false);
204 }
205
206 #[test]
help_long_flag_with_both()207 fn help_long_flag_with_both() {
208 static EXPECTED: &str = "\
209 foo 3.0
210
211 Usage: foo
212
213 Options:
214 -h, --help Print help
215 -V, --version Print version
216 ";
217 let cmd = with_both();
218 utils::assert_output(cmd, "foo --help", EXPECTED, false);
219 }
220
221 #[test]
222 #[cfg(debug_assertions)]
223 #[should_panic = "Command foo: Long option names must be unique for each argument, but '--version' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"]
override_version_long_with_user_flag()224 fn override_version_long_with_user_flag() {
225 with_version()
226 .arg(
227 clap::Arg::new("ver")
228 .long("version")
229 .action(ArgAction::SetTrue),
230 )
231 .debug_assert();
232 }
233
234 #[test]
235 #[cfg(debug_assertions)]
236 #[should_panic = "Command foo: Short option names must be unique for each argument, but '-V' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"]
override_version_short_with_user_flag()237 fn override_version_short_with_user_flag() {
238 with_version()
239 .arg(clap::Arg::new("ver").short('V').action(ArgAction::SetTrue))
240 .debug_assert();
241 }
242
243 #[test]
no_propagation_by_default_long()244 fn no_propagation_by_default_long() {
245 // Version Flag should not be propagated to subcommands
246 let res = with_subcommand().try_get_matches_from("foo bar --version".split(' '));
247
248 assert!(res.is_err());
249 let err = res.unwrap_err();
250 assert_eq!(err.kind(), ErrorKind::UnknownArgument);
251 }
252
253 #[test]
no_propagation_by_default_short()254 fn no_propagation_by_default_short() {
255 let res = with_subcommand().try_get_matches_from("foo bar -V".split(' '));
256
257 assert!(res.is_err());
258 let err = res.unwrap_err();
259 assert_eq!(err.kind(), ErrorKind::UnknownArgument);
260 }
261
262 #[test]
propagate_version_long()263 fn propagate_version_long() {
264 let res = with_subcommand()
265 .propagate_version(true)
266 .try_get_matches_from("foo bar --version".split(' '));
267
268 assert!(res.is_err());
269 let err = res.unwrap_err();
270 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
271 }
272
273 #[test]
propagate_version_short()274 fn propagate_version_short() {
275 let res = with_subcommand()
276 .propagate_version(true)
277 .try_get_matches_from("foo bar -V".split(' '));
278
279 assert!(res.is_err());
280 let err = res.unwrap_err();
281 assert_eq!(err.kind(), ErrorKind::DisplayVersion);
282 }
283
284 #[cfg(debug_assertions)]
285 #[test]
286 #[should_panic = "`ArgAction::Version` used without providing Command::version or Command::long_version"]
version_required()287 fn version_required() {
288 let _res = common()
289 .arg(clap::arg!(--version).action(ArgAction::Version))
290 .try_get_matches_from("foo -z".split(' '));
291 }
292
293 #[test]
294 #[should_panic = "Argument `version` is undefined"]
mut_arg_version_no_auto_version()295 fn mut_arg_version_no_auto_version() {
296 let _ = common().mut_arg("version", |v| v.short('z').action(ArgAction::SetTrue));
297 }
298
299 #[cfg(debug_assertions)]
300 #[test]
301 #[should_panic = "No version information via Command::version or Command::long_version to propagate"]
propagate_version_no_version_info()302 fn propagate_version_no_version_info() {
303 let _res = common()
304 .propagate_version(true)
305 .subcommand(Command::new("bar"))
306 .try_get_matches_from("foo".split(' '));
307 }
308