// Copyright 2018 Guillaume Pinot (@TeXitoi) , // Kevin Knapp (@kbknapp) , and // Andrew Hobden (@hoverbear) // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use clap::{ArgEnum, ArgValue, Parser}; #[test] fn basic() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, Bar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::Foo }, Opt::parse_from(&["", "foo"]) ); assert_eq!( Opt { arg: ArgChoice::Bar }, Opt::parse_from(&["", "bar"]) ); assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); } #[test] fn default_value() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, Bar, } impl Default for ArgChoice { fn default() -> Self { Self::Bar } } impl std::fmt::Display for ArgChoice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { std::fmt::Display::fmt(self.to_arg_value().unwrap().get_name(), f) } } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, default_value_t)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::Foo }, Opt::parse_from(&["", "foo"]) ); assert_eq!( Opt { arg: ArgChoice::Bar }, Opt::parse_from(&["", "bar"]) ); assert_eq!( Opt { arg: ArgChoice::Bar }, Opt::parse_from(&[""]) ); } #[test] fn multi_word_is_renamed_kebab() { #[derive(ArgEnum, PartialEq, Debug, Clone)] #[allow(non_camel_case_types)] enum ArgChoice { FooBar, BAR_BAZ, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::FooBar }, Opt::parse_from(&["", "foo-bar"]) ); assert_eq!( Opt { arg: ArgChoice::BAR_BAZ }, Opt::parse_from(&["", "bar-baz"]) ); assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); } #[test] fn variant_with_defined_casing() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { #[clap(rename_all = "screaming_snake")] FooBar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::FooBar }, Opt::parse_from(&["", "FOO_BAR"]) ); assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); } #[test] fn casing_is_propogated_from_parent() { #[derive(ArgEnum, PartialEq, Debug, Clone)] #[clap(rename_all = "screaming_snake")] enum ArgChoice { FooBar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::FooBar }, Opt::parse_from(&["", "FOO_BAR"]) ); assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); } #[test] fn casing_propogation_is_overridden() { #[derive(ArgEnum, PartialEq, Debug, Clone)] #[clap(rename_all = "screaming_snake")] enum ArgChoice { #[clap(rename_all = "camel")] FooBar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::FooBar }, Opt::parse_from(&["", "fooBar"]) ); assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); assert!(Opt::try_parse_from(&["", "FOO_BAR"]).is_err()); } #[test] fn case_insensitive() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, case_insensitive(true))] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::Foo }, Opt::parse_from(&["", "foo"]) ); assert_eq!( Opt { arg: ArgChoice::Foo }, Opt::parse_from(&["", "fOo"]) ); } #[test] fn case_insensitive_set_to_false() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, case_insensitive(false))] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::Foo }, Opt::parse_from(&["", "foo"]) ); assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); } #[test] fn alias() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { #[clap(alias = "TOTP")] TOTP, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, case_insensitive(false))] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::TOTP }, Opt::parse_from(&["", "totp"]) ); assert_eq!( Opt { arg: ArgChoice::TOTP }, Opt::parse_from(&["", "TOTP"]) ); } #[test] fn multiple_alias() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { #[clap(alias = "TOTP", alias = "t")] TOTP, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, case_insensitive(false))] arg: ArgChoice, } assert_eq!( Opt { arg: ArgChoice::TOTP }, Opt::parse_from(&["", "totp"]) ); assert_eq!( Opt { arg: ArgChoice::TOTP }, Opt::parse_from(&["", "TOTP"]) ); assert_eq!( Opt { arg: ArgChoice::TOTP }, Opt::parse_from(&["", "t"]) ); } #[test] fn option() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, Bar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum)] arg: Option, } assert_eq!(Opt { arg: None }, Opt::parse_from(&[""])); assert_eq!( Opt { arg: Some(ArgChoice::Foo) }, Opt::parse_from(&["", "foo"]) ); assert_eq!( Opt { arg: Some(ArgChoice::Bar) }, Opt::parse_from(&["", "bar"]) ); assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); } #[test] fn vector() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, Bar, } #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(arg_enum, short, long)] arg: Vec, } assert_eq!(Opt { arg: vec![] }, Opt::parse_from(&[""])); assert_eq!( Opt { arg: vec![ArgChoice::Foo] }, Opt::parse_from(&["", "-a", "foo"]) ); assert_eq!( Opt { arg: vec![ArgChoice::Foo, ArgChoice::Bar] }, Opt::parse_from(&["", "-a", "foo", "bar"]) ); assert!(Opt::try_parse_from(&["", "-a", "fOo"]).is_err()); } #[test] fn skip_variant() { #[derive(ArgEnum, PartialEq, Debug, Clone)] #[allow(dead_code)] // silence warning about `Baz` being unused enum ArgChoice { Foo, Bar, #[clap(skip)] Baz, } assert_eq!( ArgChoice::value_variants() .iter() .map(ArgEnum::to_arg_value) .map(Option::unwrap) .collect::>(), vec![ArgValue::new("foo"), ArgValue::new("bar")] ); assert!(ArgChoice::from_str("foo", true).is_ok()); assert!(ArgChoice::from_str("bar", true).is_ok()); assert!(ArgChoice::from_str("baz", true).is_err()); } #[test] fn from_str_invalid() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, } assert!(ArgChoice::from_str("bar", true).is_err()); }