]> git.proxmox.com Git - rustc.git/blame - vendor/structopt/tests/subcommands.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / vendor / structopt / tests / subcommands.rs
CommitLineData
f20569fa
XL
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
9mod utils;
10
11use structopt::StructOpt;
12use utils::*;
13
14#[derive(StructOpt, PartialEq, Debug)]
15enum 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]
35fn 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]
55fn 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]
73fn 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)]
85enum Opt2 {
86 DoSomething { arg: String },
87}
88
89#[test]
90/// This test is specifically to make sure that hyphenated subcommands get
91/// processed correctly.
92fn 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)]
102enum Opt3 {
103 Add,
104 Init,
105 Fetch,
106}
107
108#[test]
109fn 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")]
126struct Add {
127 file: String,
128}
129/// Not shown
130#[derive(StructOpt, PartialEq, Debug)]
131struct Fetch {
132 remote: String,
133}
134#[derive(StructOpt, PartialEq, Debug)]
135enum 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]
145fn 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]
171fn 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]
194fn 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]
216fn 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]
256fn 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]
282fn 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}
a2a8927a
XL
304
305#[test]
306fn 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}