blob: 803abb4664ab9b00567b589536474b67110a6fa1 [file] [log] [blame]
Matthew Maurer32e76692020-06-02 11:15:15 -07001// 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
9use structopt::StructOpt;
10
11#[test]
12fn required_option() {
13 #[derive(StructOpt, PartialEq, Debug)]
14 struct Opt {
15 #[structopt(short, long)]
16 arg: i32,
17 }
18 assert_eq!(
19 Opt { arg: 42 },
20 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
21 );
22 assert_eq!(
23 Opt { arg: 42 },
24 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "42"]))
25 );
26 assert_eq!(
27 Opt { arg: 42 },
28 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--arg", "42"]))
29 );
30 assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
31 assert!(Opt::clap()
32 .get_matches_from_safe(&["test", "-a42", "-a24"])
33 .is_err());
34}
35
36#[test]
37fn optional_option() {
38 #[derive(StructOpt, PartialEq, Debug)]
39 struct Opt {
40 #[structopt(short)]
41 arg: Option<i32>,
42 }
43 assert_eq!(
44 Opt { arg: Some(42) },
45 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
46 );
47 assert_eq!(
48 Opt { arg: None },
49 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
50 );
51 assert!(Opt::clap()
52 .get_matches_from_safe(&["test", "-a42", "-a24"])
53 .is_err());
54}
55
56#[test]
57fn option_with_default() {
58 #[derive(StructOpt, PartialEq, Debug)]
59 struct Opt {
60 #[structopt(short, default_value = "42")]
61 arg: i32,
62 }
63 assert_eq!(
64 Opt { arg: 24 },
65 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
66 );
67 assert_eq!(
68 Opt { arg: 42 },
69 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
70 );
71 assert!(Opt::clap()
72 .get_matches_from_safe(&["test", "-a42", "-a24"])
73 .is_err());
74}
75
76#[test]
77fn option_with_raw_default() {
78 #[derive(StructOpt, PartialEq, Debug)]
79 struct Opt {
80 #[structopt(short, default_value = "42")]
81 arg: i32,
82 }
83 assert_eq!(
84 Opt { arg: 24 },
85 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
86 );
87 assert_eq!(
88 Opt { arg: 42 },
89 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
90 );
91 assert!(Opt::clap()
92 .get_matches_from_safe(&["test", "-a42", "-a24"])
93 .is_err());
94}
95
96#[test]
97fn options() {
98 #[derive(StructOpt, PartialEq, Debug)]
99 struct Opt {
100 #[structopt(short, long)]
101 arg: Vec<i32>,
102 }
103 assert_eq!(
104 Opt { arg: vec![24] },
105 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
106 );
107 assert_eq!(
108 Opt { arg: vec![] },
109 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
110 );
111 assert_eq!(
112 Opt { arg: vec![24, 42] },
113 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24", "--arg", "42"]))
114 );
115}
116
117#[test]
118fn empy_default_value() {
119 #[derive(StructOpt, PartialEq, Debug)]
120 struct Opt {
121 #[structopt(short, default_value = "")]
122 arg: String,
123 }
124 assert_eq!(Opt { arg: "".into() }, Opt::from_iter(&["test"]));
125 assert_eq!(
126 Opt { arg: "foo".into() },
127 Opt::from_iter(&["test", "-afoo"])
128 );
129}
130
131#[test]
132fn option_from_str() {
133 #[derive(Debug, PartialEq)]
134 struct A;
135
136 impl<'a> From<&'a str> for A {
137 fn from(_: &str) -> A {
138 A
139 }
140 }
141
142 #[derive(Debug, StructOpt, PartialEq)]
143 struct Opt {
144 #[structopt(parse(from_str))]
145 a: Option<A>,
146 }
147
148 assert_eq!(Opt { a: None }, Opt::from_iter(&["test"]));
149 assert_eq!(Opt { a: Some(A) }, Opt::from_iter(&["test", "foo"]));
150}
151
152#[test]
153fn optional_argument_for_optional_option() {
154 #[derive(StructOpt, PartialEq, Debug)]
155 struct Opt {
156 #[structopt(short)]
157 #[allow(clippy::option_option)]
158 arg: Option<Option<i32>>,
159 }
160 assert_eq!(
161 Opt {
162 arg: Some(Some(42))
163 },
164 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
165 );
166 assert_eq!(
167 Opt { arg: Some(None) },
168 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
169 );
170 assert_eq!(
171 Opt { arg: None },
172 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
173 );
174 assert!(Opt::clap()
175 .get_matches_from_safe(&["test", "-a42", "-a24"])
176 .is_err());
177}
178
179#[test]
180fn two_option_options() {
181 #[derive(StructOpt, PartialEq, Debug)]
182 #[allow(clippy::option_option)]
183 struct Opt {
184 #[structopt(short)]
185 arg: Option<Option<i32>>,
186
187 #[structopt(long)]
188 field: Option<Option<String>>,
189 }
190 assert_eq!(
191 Opt {
192 arg: Some(Some(42)),
193 field: Some(Some("f".into()))
194 },
195 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field", "f"]))
196 );
197 assert_eq!(
198 Opt {
199 arg: Some(Some(42)),
200 field: Some(None)
201 },
202 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field"]))
203 );
204 assert_eq!(
205 Opt {
206 arg: Some(None),
207 field: Some(None)
208 },
209 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field"]))
210 );
211 assert_eq!(
212 Opt {
213 arg: Some(None),
214 field: Some(Some("f".into()))
215 },
216 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field", "f"]))
217 );
218 assert_eq!(
219 Opt {
220 arg: None,
221 field: Some(None)
222 },
223 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--field"]))
224 );
225 assert_eq!(
226 Opt {
227 arg: None,
228 field: None
229 },
230 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
231 );
232}
233
234#[test]
235fn optional_vec() {
236 #[derive(StructOpt, PartialEq, Debug)]
237 struct Opt {
238 #[structopt(short)]
239 arg: Option<Vec<i32>>,
240 }
241 assert_eq!(
242 Opt { arg: Some(vec![1]) },
243 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1"]))
244 );
245
246 assert_eq!(
247 Opt {
248 arg: Some(vec![1, 2])
249 },
250 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2"]))
251 );
252
253 assert_eq!(
254 Opt {
255 arg: Some(vec![1, 2])
256 },
257 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-a"]))
258 );
259
260 assert_eq!(
261 Opt {
262 arg: Some(vec![1, 2])
263 },
264 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a", "-a2"]))
265 );
266
267 assert_eq!(
268 Opt {
269 arg: Some(vec![1, 2])
270 },
271 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2"]))
272 );
273
274 assert_eq!(
275 Opt {
276 arg: Some(vec![1, 2, 3])
277 },
278 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2", "-a", "3"]))
279 );
280
281 assert_eq!(
282 Opt { arg: Some(vec![]) },
283 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
284 );
285
286 assert_eq!(
287 Opt { arg: Some(vec![]) },
288 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-a"]))
289 );
290
291 assert_eq!(
292 Opt { arg: None },
293 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
294 );
295}
296
297#[test]
298fn two_optional_vecs() {
299 #[derive(StructOpt, PartialEq, Debug)]
300 struct Opt {
301 #[structopt(short)]
302 arg: Option<Vec<i32>>,
303
304 #[structopt(short)]
305 b: Option<Vec<i32>>,
306 }
307
308 assert_eq!(
309 Opt {
310 arg: Some(vec![1]),
311 b: Some(vec![])
312 },
313 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "-b"]))
314 );
315
316 assert_eq!(
317 Opt {
318 arg: Some(vec![1]),
319 b: Some(vec![])
320 },
321 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-b", "-a1"]))
322 );
323
324 assert_eq!(
325 Opt {
326 arg: Some(vec![1, 2]),
327 b: Some(vec![1, 2])
328 },
329 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-b1", "-b2"]))
330 );
331
332 assert_eq!(
333 Opt { arg: None, b: None },
334 Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
335 );
336}