1#![cfg(feature = "env")]
2
3use std::env;
4use std::ffi::OsStr;
5
6use clap::{arg, builder::FalseyValueParser, Arg, ArgAction, Command};
7
8#[test]
9fn env() {
10    env::set_var("CLP_TEST_ENV", "env");
11
12    let r = Command::new("df")
13        .arg(
14            arg!([arg] "some opt")
15                .env("CLP_TEST_ENV")
16                .action(ArgAction::Set),
17        )
18        .try_get_matches_from(vec![""]);
19
20    assert!(r.is_ok(), "{}", r.unwrap_err());
21    let m = r.unwrap();
22    assert!(m.contains_id("arg"));
23    assert_eq!(
24        m.value_source("arg").unwrap(),
25        clap::parser::ValueSource::EnvVariable
26    );
27    assert_eq!(
28        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
29        "env"
30    );
31}
32
33#[test]
34fn env_bool_literal() {
35    env::set_var("CLP_TEST_FLAG_TRUE", "On");
36    env::set_var("CLP_TEST_FLAG_FALSE", "nO");
37
38    let r = Command::new("df")
39        .arg(
40            Arg::new("present")
41                .short('p')
42                .env("CLP_TEST_FLAG_TRUE")
43                .action(ArgAction::SetTrue)
44                .value_parser(FalseyValueParser::new()),
45        )
46        .arg(
47            Arg::new("negated")
48                .short('n')
49                .env("CLP_TEST_FLAG_FALSE")
50                .action(ArgAction::SetTrue)
51                .value_parser(FalseyValueParser::new()),
52        )
53        .arg(
54            Arg::new("absent")
55                .short('a')
56                .env("CLP_TEST_FLAG_ABSENT")
57                .action(ArgAction::SetTrue)
58                .value_parser(FalseyValueParser::new()),
59        )
60        .try_get_matches_from(vec![""]);
61
62    assert!(r.is_ok(), "{}", r.unwrap_err());
63    let m = r.unwrap();
64    assert!(*m.get_one::<bool>("present").expect("defaulted by clap"));
65    assert!(!*m.get_one::<bool>("negated").expect("defaulted by clap"));
66    assert!(!*m.get_one::<bool>("absent").expect("defaulted by clap"));
67}
68
69#[test]
70fn env_os() {
71    env::set_var("CLP_TEST_ENV_OS", "env");
72
73    let r = Command::new("df")
74        .arg(
75            arg!([arg] "some opt")
76                .env(OsStr::new("CLP_TEST_ENV_OS"))
77                .action(ArgAction::Set),
78        )
79        .try_get_matches_from(vec![""]);
80
81    assert!(r.is_ok(), "{}", r.unwrap_err());
82    let m = r.unwrap();
83    assert!(m.contains_id("arg"));
84    assert_eq!(
85        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
86        "env"
87    );
88}
89
90#[test]
91fn no_env() {
92    // All the other tests use the presence of the Environment variable...
93    // we need another variable just in case one of the others is running at the same time...
94    env::remove_var("CLP_TEST_ENV_NONE");
95
96    let r = Command::new("df")
97        .arg(
98            arg!([arg] "some opt")
99                .env("CLP_TEST_ENV_NONE")
100                .action(ArgAction::Set),
101        )
102        .try_get_matches_from(vec![""]);
103
104    assert!(r.is_ok(), "{}", r.unwrap_err());
105    let m = r.unwrap();
106    assert!(!m.contains_id("arg"));
107    assert_eq!(m.value_source("arg"), None);
108    assert_eq!(m.get_one::<String>("arg").map(|v| v.as_str()), None);
109}
110
111#[test]
112fn no_env_no_takes_value() {
113    // All the other tests use the presence of the Environment variable...
114    // we need another variable just in case one of the others is running at the same time...
115    env::remove_var("CLP_TEST_ENV_NONE");
116
117    let r = Command::new("df")
118        .arg(arg!([arg] "some opt").env("CLP_TEST_ENV_NONE"))
119        .try_get_matches_from(vec![""]);
120
121    assert!(r.is_ok(), "{}", r.unwrap_err());
122    let m = r.unwrap();
123    assert!(!m.contains_id("arg"));
124    assert_eq!(m.value_source("arg"), None);
125    assert_eq!(m.get_one::<String>("arg").map(|v| v.as_str()), None);
126}
127
128#[test]
129fn with_default() {
130    env::set_var("CLP_TEST_ENV_WD", "env");
131
132    let r = Command::new("df")
133        .arg(
134            arg!([arg] "some opt")
135                .env("CLP_TEST_ENV_WD")
136                .action(ArgAction::Set)
137                .default_value("default"),
138        )
139        .try_get_matches_from(vec![""]);
140
141    assert!(r.is_ok(), "{}", r.unwrap_err());
142    let m = r.unwrap();
143    assert!(m.contains_id("arg"));
144    assert_eq!(
145        m.value_source("arg").unwrap(),
146        clap::parser::ValueSource::EnvVariable
147    );
148    assert_eq!(
149        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
150        "env"
151    );
152}
153
154#[test]
155fn opt_user_override() {
156    env::set_var("CLP_TEST_ENV_OR", "env");
157
158    let r = Command::new("df")
159        .arg(
160            arg!(--arg [FILE] "some arg")
161                .env("CLP_TEST_ENV_OR")
162                .action(ArgAction::Set),
163        )
164        .try_get_matches_from(vec!["", "--arg", "opt"]);
165
166    assert!(r.is_ok(), "{}", r.unwrap_err());
167    let m = r.unwrap();
168    assert!(m.contains_id("arg"));
169    assert_eq!(
170        m.value_source("arg").unwrap(),
171        clap::parser::ValueSource::CommandLine
172    );
173    assert_eq!(
174        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
175        "opt"
176    );
177
178    // see https://github.com/clap-rs/clap/issues/1835
179    let values: Vec<_> = m
180        .get_many::<String>("arg")
181        .unwrap()
182        .map(|v| v.as_str())
183        .collect();
184    assert_eq!(values, vec!["opt"]);
185}
186
187#[test]
188fn positionals() {
189    env::set_var("CLP_TEST_ENV_P", "env");
190
191    let r = Command::new("df")
192        .arg(
193            arg!([arg] "some opt")
194                .env("CLP_TEST_ENV_P")
195                .action(ArgAction::Set),
196        )
197        .try_get_matches_from(vec![""]);
198
199    assert!(r.is_ok(), "{}", r.unwrap_err());
200    let m = r.unwrap();
201    assert!(m.contains_id("arg"));
202    assert_eq!(
203        m.value_source("arg").unwrap(),
204        clap::parser::ValueSource::EnvVariable
205    );
206    assert_eq!(
207        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
208        "env"
209    );
210}
211
212#[test]
213fn positionals_user_override() {
214    env::set_var("CLP_TEST_ENV_POR", "env");
215
216    let r = Command::new("df")
217        .arg(
218            arg!([arg] "some opt")
219                .env("CLP_TEST_ENV_POR")
220                .action(ArgAction::Set),
221        )
222        .try_get_matches_from(vec!["", "opt"]);
223
224    assert!(r.is_ok(), "{}", r.unwrap_err());
225    let m = r.unwrap();
226    assert!(m.contains_id("arg"));
227    assert_eq!(
228        m.value_source("arg").unwrap(),
229        clap::parser::ValueSource::CommandLine
230    );
231    assert_eq!(
232        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
233        "opt"
234    );
235
236    // see https://github.com/clap-rs/clap/issues/1835
237    let values: Vec<_> = m
238        .get_many::<String>("arg")
239        .unwrap()
240        .map(|v| v.as_str())
241        .collect();
242    assert_eq!(values, vec!["opt"]);
243}
244
245#[test]
246fn multiple_one() {
247    env::set_var("CLP_TEST_ENV_MO", "env");
248
249    let r = Command::new("df")
250        .arg(
251            arg!([arg] "some opt")
252                .env("CLP_TEST_ENV_MO")
253                .action(ArgAction::Set)
254                .value_delimiter(',')
255                .num_args(1..),
256        )
257        .try_get_matches_from(vec![""]);
258
259    assert!(r.is_ok(), "{}", r.unwrap_err());
260    let m = r.unwrap();
261    assert!(m.contains_id("arg"));
262    assert_eq!(
263        m.get_many::<String>("arg")
264            .unwrap()
265            .map(|v| v.as_str())
266            .collect::<Vec<_>>(),
267        vec!["env"]
268    );
269}
270
271#[test]
272fn multiple_three() {
273    env::set_var("CLP_TEST_ENV_MULTI1", "env1,env2,env3");
274
275    let r = Command::new("df")
276        .arg(
277            arg!([arg] "some opt")
278                .env("CLP_TEST_ENV_MULTI1")
279                .action(ArgAction::Set)
280                .value_delimiter(',')
281                .num_args(1..),
282        )
283        .try_get_matches_from(vec![""]);
284
285    assert!(r.is_ok(), "{}", r.unwrap_err());
286    let m = r.unwrap();
287    assert!(m.contains_id("arg"));
288    assert_eq!(
289        m.get_many::<String>("arg")
290            .unwrap()
291            .map(|v| v.as_str())
292            .collect::<Vec<_>>(),
293        vec!["env1", "env2", "env3"]
294    );
295}
296
297#[test]
298fn multiple_no_delimiter() {
299    env::set_var("CLP_TEST_ENV_MULTI2", "env1 env2 env3");
300
301    let r = Command::new("df")
302        .arg(
303            arg!([arg] "some opt")
304                .env("CLP_TEST_ENV_MULTI2")
305                .action(ArgAction::Set)
306                .num_args(1..),
307        )
308        .try_get_matches_from(vec![""]);
309
310    assert!(r.is_ok(), "{}", r.unwrap_err());
311    let m = r.unwrap();
312    assert!(m.contains_id("arg"));
313    assert_eq!(
314        m.get_many::<String>("arg")
315            .unwrap()
316            .map(|v| v.as_str())
317            .collect::<Vec<_>>(),
318        vec!["env1 env2 env3"]
319    );
320}
321
322#[test]
323fn possible_value() {
324    env::set_var("CLP_TEST_ENV_PV", "env");
325
326    let r = Command::new("df")
327        .arg(
328            arg!([arg] "some opt")
329                .env("CLP_TEST_ENV_PV")
330                .action(ArgAction::Set)
331                .value_parser(["env"]),
332        )
333        .try_get_matches_from(vec![""]);
334
335    assert!(r.is_ok(), "{}", r.unwrap_err());
336    let m = r.unwrap();
337    assert!(m.contains_id("arg"));
338    assert_eq!(
339        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
340        "env"
341    );
342}
343
344#[test]
345fn not_possible_value() {
346    env::set_var("CLP_TEST_ENV_NPV", "env");
347
348    let r = Command::new("df")
349        .arg(
350            arg!([arg] "some opt")
351                .env("CLP_TEST_ENV_NPV")
352                .action(ArgAction::Set)
353                .value_parser(["never"]),
354        )
355        .try_get_matches_from(vec![""]);
356
357    assert!(r.is_err());
358}
359
360#[test]
361fn value_parser() {
362    env::set_var("CLP_TEST_ENV_VDOR", "env");
363
364    let r = Command::new("df")
365        .arg(
366            arg!([arg] "some opt")
367                .env("CLP_TEST_ENV_VDOR")
368                .action(ArgAction::Set)
369                .value_parser(|s: &str| -> Result<String, String> {
370                    if s == "env" {
371                        Ok(s.to_owned())
372                    } else {
373                        Err("not equal".to_owned())
374                    }
375                }),
376        )
377        .try_get_matches_from(vec![""]);
378
379    assert!(r.is_ok(), "{}", r.unwrap_err());
380    let m = r.unwrap();
381    assert!(m.contains_id("arg"));
382    assert_eq!(
383        m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
384        "env"
385    );
386}
387
388#[test]
389fn value_parser_output() {
390    env::set_var("CLP_TEST_ENV_VO", "42");
391
392    let m = Command::new("df")
393        .arg(
394            arg!([arg] "some opt")
395                .env("CLP_TEST_ENV_VO")
396                .action(ArgAction::Set)
397                .value_parser(clap::value_parser!(i32)),
398        )
399        .try_get_matches_from(vec![""])
400        .unwrap();
401
402    assert_eq!(*m.get_one::<i32>("arg").unwrap(), 42);
403}
404
405#[test]
406fn value_parser_invalid() {
407    env::set_var("CLP_TEST_ENV_IV", "env");
408
409    let r = Command::new("df")
410        .arg(
411            arg!([arg] "some opt")
412                .env("CLP_TEST_ENV_IV")
413                .action(ArgAction::Set)
414                .value_parser(|s: &str| -> Result<String, String> {
415                    if s != "env" {
416                        Ok(s.to_owned())
417                    } else {
418                        Err("is equal".to_string())
419                    }
420                }),
421        )
422        .try_get_matches_from(vec![""]);
423
424    assert!(r.is_err());
425}
426