]> git.proxmox.com Git - rustc.git/blob - vendor/structopt/tests/subcommands.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / vendor / structopt / tests / subcommands.rs
1 // Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 mod utils;
10
11 use structopt::StructOpt;
12 use utils::*;
13
14 #[derive(StructOpt, PartialEq, Debug)]
15 enum Opt {
16 /// Fetch stuff from GitHub
17 Fetch {
18 #[structopt(long)]
19 all: bool,
20 #[structopt(short, long)]
21 /// Overwrite local branches.
22 force: bool,
23 repo: String,
24 },
25
26 Add {
27 #[structopt(short, long)]
28 interactive: bool,
29 #[structopt(short, long)]
30 verbose: bool,
31 },
32 }
33
34 #[test]
35 fn test_fetch() {
36 assert_eq!(
37 Opt::Fetch {
38 all: true,
39 force: false,
40 repo: "origin".to_string()
41 },
42 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "--all", "origin"]))
43 );
44 assert_eq!(
45 Opt::Fetch {
46 all: false,
47 force: true,
48 repo: "origin".to_string()
49 },
50 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "-f", "origin"]))
51 );
52 }
53
54 #[test]
55 fn test_add() {
56 assert_eq!(
57 Opt::Add {
58 interactive: false,
59 verbose: false
60 },
61 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"]))
62 );
63 assert_eq!(
64 Opt::Add {
65 interactive: true,
66 verbose: true
67 },
68 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add", "-i", "-v"]))
69 );
70 }
71
72 #[test]
73 fn test_no_parse() {
74 let result = Opt::clap().get_matches_from_safe(&["test", "badcmd", "-i", "-v"]);
75 assert!(result.is_err());
76
77 let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badoption"]);
78 assert!(result.is_err());
79
80 let result = Opt::clap().get_matches_from_safe(&["test"]);
81 assert!(result.is_err());
82 }
83
84 #[derive(StructOpt, PartialEq, Debug)]
85 enum Opt2 {
86 DoSomething { arg: String },
87 }
88
89 #[test]
90 /// This test is specifically to make sure that hyphenated subcommands get
91 /// processed correctly.
92 fn test_hyphenated_subcommands() {
93 assert_eq!(
94 Opt2::DoSomething {
95 arg: "blah".to_string()
96 },
97 Opt2::from_clap(&Opt2::clap().get_matches_from(&["test", "do-something", "blah"]))
98 );
99 }
100
101 #[derive(StructOpt, PartialEq, Debug)]
102 enum Opt3 {
103 Add,
104 Init,
105 Fetch,
106 }
107
108 #[test]
109 fn test_null_commands() {
110 assert_eq!(
111 Opt3::Add,
112 Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "add"]))
113 );
114 assert_eq!(
115 Opt3::Init,
116 Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "init"]))
117 );
118 assert_eq!(
119 Opt3::Fetch,
120 Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "fetch"]))
121 );
122 }
123
124 #[derive(StructOpt, PartialEq, Debug)]
125 #[structopt(about = "Not shown")]
126 struct Add {
127 file: String,
128 }
129 /// Not shown
130 #[derive(StructOpt, PartialEq, Debug)]
131 struct Fetch {
132 remote: String,
133 }
134 #[derive(StructOpt, PartialEq, Debug)]
135 enum Opt4 {
136 // Not shown
137 /// Add a file
138 Add(Add),
139 Init,
140 /// download history from remote
141 Fetch(Fetch),
142 }
143
144 #[test]
145 fn test_tuple_commands() {
146 assert_eq!(
147 Opt4::Add(Add {
148 file: "f".to_string()
149 }),
150 Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "add", "f"]))
151 );
152 assert_eq!(
153 Opt4::Init,
154 Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "init"]))
155 );
156 assert_eq!(
157 Opt4::Fetch(Fetch {
158 remote: "origin".to_string()
159 }),
160 Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "fetch", "origin"]))
161 );
162
163 let output = get_long_help::<Opt4>();
164
165 assert!(output.contains("download history from remote"));
166 assert!(output.contains("Add a file"));
167 assert!(!output.contains("Not shown"));
168 }
169
170 #[test]
171 fn enum_in_enum_subsubcommand() {
172 #[derive(StructOpt, Debug, PartialEq)]
173 pub enum Opt {
174 Daemon(DaemonCommand),
175 }
176
177 #[derive(StructOpt, Debug, PartialEq)]
178 pub enum DaemonCommand {
179 Start,
180 Stop,
181 }
182
183 let result = Opt::clap().get_matches_from_safe(&["test"]);
184 assert!(result.is_err());
185
186 let result = Opt::clap().get_matches_from_safe(&["test", "daemon"]);
187 assert!(result.is_err());
188
189 let result = Opt::from_iter(&["test", "daemon", "start"]);
190 assert_eq!(Opt::Daemon(DaemonCommand::Start), result);
191 }
192
193 #[test]
194 fn flatten_enum() {
195 #[derive(StructOpt, Debug, PartialEq)]
196 struct Opt {
197 #[structopt(flatten)]
198 sub_cmd: SubCmd,
199 }
200 #[derive(StructOpt, Debug, PartialEq)]
201 enum SubCmd {
202 Foo,
203 Bar,
204 }
205
206 assert!(Opt::from_iter_safe(&["test"]).is_err());
207 assert_eq!(
208 Opt::from_iter(&["test", "foo"]),
209 Opt {
210 sub_cmd: SubCmd::Foo
211 }
212 );
213 }
214
215 #[test]
216 fn external_subcommand() {
217 #[derive(Debug, PartialEq, StructOpt)]
218 struct Opt {
219 #[structopt(subcommand)]
220 sub: Subcommands,
221 }
222
223 #[derive(Debug, PartialEq, StructOpt)]
224 enum Subcommands {
225 Add,
226 Remove,
227 #[structopt(external_subcommand)]
228 Other(Vec<String>),
229 }
230
231 assert_eq!(
232 Opt::from_iter(&["test", "add"]),
233 Opt {
234 sub: Subcommands::Add
235 }
236 );
237
238 assert_eq!(
239 Opt::from_iter(&["test", "remove"]),
240 Opt {
241 sub: Subcommands::Remove
242 }
243 );
244
245 assert_eq!(
246 Opt::from_iter(&["test", "git", "status"]),
247 Opt {
248 sub: Subcommands::Other(vec!["git".into(), "status".into()])
249 }
250 );
251
252 assert!(Opt::from_iter_safe(&["test"]).is_err());
253 }
254
255 #[test]
256 fn external_subcommand_os_string() {
257 use std::ffi::OsString;
258
259 #[derive(Debug, PartialEq, StructOpt)]
260 struct Opt {
261 #[structopt(subcommand)]
262 sub: Subcommands,
263 }
264
265 #[derive(Debug, PartialEq, StructOpt)]
266 enum Subcommands {
267 #[structopt(external_subcommand)]
268 Other(Vec<OsString>),
269 }
270
271 assert_eq!(
272 Opt::from_iter(&["test", "git", "status"]),
273 Opt {
274 sub: Subcommands::Other(vec!["git".into(), "status".into()])
275 }
276 );
277
278 assert!(Opt::from_iter_safe(&["test"]).is_err());
279 }
280
281 #[test]
282 fn external_subcommand_optional() {
283 #[derive(Debug, PartialEq, StructOpt)]
284 struct Opt {
285 #[structopt(subcommand)]
286 sub: Option<Subcommands>,
287 }
288
289 #[derive(Debug, PartialEq, StructOpt)]
290 enum Subcommands {
291 #[structopt(external_subcommand)]
292 Other(Vec<String>),
293 }
294
295 assert_eq!(
296 Opt::from_iter(&["test", "git", "status"]),
297 Opt {
298 sub: Some(Subcommands::Other(vec!["git".into(), "status".into()]))
299 }
300 );
301
302 assert_eq!(Opt::from_iter(&["test"]), Opt { sub: None });
303 }
304
305 #[test]
306 fn skip_subcommand() {
307 #[derive(Debug, PartialEq, StructOpt)]
308 struct Opt {
309 #[structopt(subcommand)]
310 sub: Subcommands,
311 }
312
313 #[derive(Debug, PartialEq, StructOpt)]
314 enum Subcommands {
315 Add,
316 Remove,
317
318 #[allow(dead_code)]
319 #[structopt(skip)]
320 Skip,
321 }
322
323 assert_eq!(
324 Opt::from_iter(&["test", "add"]),
325 Opt {
326 sub: Subcommands::Add
327 }
328 );
329
330 assert_eq!(
331 Opt::from_iter(&["test", "remove"]),
332 Opt {
333 sub: Subcommands::Remove
334 }
335 );
336
337 let res = Opt::from_iter_safe(&["test", "skip"]);
338 assert!(
339 matches!(
340 res,
341 Err(clap::Error {
342 kind: clap::ErrorKind::UnknownArgument,
343 ..
344 })
345 ),
346 "Unexpected result: {:?}",
347 res
348 );
349 }