Skip to content
This repository was archived by the owner on May 11, 2020. It is now read-only.

Commit

Permalink
Merge pull request #14 from kbknapp/make-tests-pass
Browse files Browse the repository at this point in the history
tests: Make tests pass
  • Loading branch information
kbknapp authored Jul 20, 2018
2 parents 1b257f5 + 48f83e0 commit 2c670d5
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 254 deletions.
14 changes: 8 additions & 6 deletions src/derives/clap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ fn gen_app_augmentation(

// @TODO remove unneccessary builders
let modifier = match ty {
Ty::Bool => quote!( .takes_value(false).multiple(false) ),
Ty::Option => quote!( .takes_value(true).multiple(false) #validator ),
Ty::Bool => quote!(),
Ty::Option => quote!( .takes_value(true) #validator ),
Ty::Vec => quote!( .takes_value(true).multiple(true) #validator ),
Ty::Other if occurences => quote!( .takes_value(false).multiple(true) ),
Ty::Other if occurences => quote!( .multiple_occurrences(true) ),
Ty::Other => {
let required = !attrs.has_method("default_value");
quote!( .takes_value(true).multiple(false).required(#required) #validator )
quote!( .takes_value(true).required(#required) #validator )
}
};
let methods = attrs.methods();
Expand Down Expand Up @@ -242,8 +242,6 @@ fn clap_impl_for_struct(
let parse_fns = gen_parse_fns(name);

quote! {
use ::clap::{FromArgMatches, IntoApp};

#[allow(unused_variables)]
impl ::clap::Clap for #name { }

Expand Down Expand Up @@ -315,24 +313,28 @@ pub fn derive_clap(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
fn gen_parse_fns(name: &syn::Ident) -> proc_macro2::TokenStream {
quote! {
fn parse() -> #name {
use ::clap::{FromArgMatches, IntoApp};
#name::from_argmatches(&#name::into_app().get_matches())
}

fn try_parse() -> ::std::result::Result<#name, ::clap::Error> {
use ::clap::{FromArgMatches, IntoApp};
Ok(#name::from_argmatches(&#name::into_app().get_matches_safe()?))
}

fn parse_from<I, T>(itr: I) -> #name
where
I: ::std::iter::IntoIterator<Item = T>,
T: Into<::std::ffi::OsString> + Clone {
use ::clap::{FromArgMatches, IntoApp};
#name::from_argmatches(&#name::into_app().get_matches_from(itr))
}

fn try_parse_from<I, T>(itr: I) -> ::std::result::Result<#name, ::clap::Error>
where
I: ::std::iter::IntoIterator<Item = T>,
T: Into<::std::ffi::OsString> + Clone {
use ::clap::{FromArgMatches, IntoApp};
Ok(#name::from_argmatches(&#name::into_app().get_matches_from_safe(itr)?))
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/derives/from_argmatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub fn gen_from_argmatches_impl_for_struct(

impl<'a> From<::clap::ArgMatches<'a>> for #name {
fn from(m: ::clap::ArgMatches) -> Self {
use ::clap::FromArgMatches;
<Self as ::clap::FromArgMatches>::from_argmatches(&m)
}
}
Expand Down Expand Up @@ -153,6 +154,7 @@ pub fn gen_from_argmatches_impl_for_enum(name: &syn::Ident) -> proc_macro2::Toke

impl<'a> From<::clap::ArgMatches<'a>> for #name {
fn from(m: ::clap::ArgMatches) -> Self {
use ::clap::FromArgMatches;
<Self as ::clap::FromArgMatches>::from_argmatches(&m)
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/derives/into_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn gen_into_app_impl_for_struct(

impl<'a, 'b> Into<::clap::App<'a, 'b>> for #name {
fn into(self) -> ::clap::App<'a, 'b> {
use ::clap::IntoApp;
<#name as ::clap::IntoApp>::into_app()
}
}
Expand Down Expand Up @@ -83,6 +84,7 @@ pub fn gen_into_app_impl_for_enum(

impl<'a, 'b> Into<::clap::App<'a, 'b>> for #name {
fn into(self) -> ::clap::App<'a, 'b> {
use ::clap::IntoApp;
<#name as ::clap::IntoApp>::into_app()
}
}
Expand Down
26 changes: 5 additions & 21 deletions tests/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ fn required_argument() {
arg: i32,
}
assert_eq!(Opt { arg: 42 }, Opt::parse_from(&["test", "42"]));
assert!(Opt::into_app().get_matches_from_safe(&["test"]).is_err());
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "42", "24"])
.is_err()
);
assert!(Opt::try_parse_from(&["test"]).is_err());
assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err());
}

#[test]
Expand All @@ -40,11 +36,7 @@ fn optional_argument() {
}
assert_eq!(Opt { arg: Some(42) }, Opt::parse_from(&["test", "42"]));
assert_eq!(Opt { arg: None }, Opt::parse_from(&["test"]));
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "42", "24"])
.is_err()
);
assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err());
}

#[test]
Expand All @@ -56,11 +48,7 @@ fn argument_with_default() {
}
assert_eq!(Opt { arg: 24 }, Opt::parse_from(&["test", "24"]));
assert_eq!(Opt { arg: 42 }, Opt::parse_from(&["test"]));
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "42", "24"])
.is_err()
);
assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err());
}

#[test]
Expand All @@ -72,11 +60,7 @@ fn argument_with_raw_default() {
}
assert_eq!(Opt { arg: 24 }, Opt::parse_from(&["test", "24"]));
assert_eq!(Opt { arg: 42 }, Opt::parse_from(&["test"]));
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "42", "24"])
.is_err()
);
assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err());
}

#[test]
Expand Down
23 changes: 20 additions & 3 deletions tests/author_version_about.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use clap::Clap;

#[test]
fn no_author_version_about() {
use clap::IntoApp;

#[derive(Clap, PartialEq, Debug)]
#[clap(name = "foo", about = "", author = "", version = "")]
struct Opt {}
Expand All @@ -30,16 +32,31 @@ fn no_author_version_about() {
assert!(output.starts_with("foo \n\nUSAGE:"));
}

static ENV_HELP: &str = "clap_derive 0.3.0
Guillaume Pinot <[email protected]>, Kevin K. <[email protected]>, hoverbear <[email protected]>
Parse command line argument by defining a struct, derive crate.
USAGE:
clap_derive
FLAGS:
-h, --help
Prints help information
-V, --version
Prints version information
";

#[test]
fn use_env() {
use clap::IntoApp;

#[derive(Clap, PartialEq, Debug)]
#[clap()]
struct Opt {}

let mut output = Vec::new();
Opt::into_app().write_long_help(&mut output).unwrap();
let output = String::from_utf8(output).unwrap();
assert!(output.starts_with("structopt 0.2."));
assert!(output.contains("Guillaume Pinot <[email protected]>, others"));
assert!(output.contains("Parse command line argument by defining a struct."));
assert_eq!(output, ENV_HELP);
}
54 changes: 25 additions & 29 deletions tests/custom-string-parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern crate clap;

use clap::Clap;

use std::ffi::{OsStr, OsString};
use std::ffi::OsStr;
use std::num::ParseIntError;
use std::path::PathBuf;

Expand Down Expand Up @@ -53,10 +53,10 @@ fn test_path_opt_simple() {
option_path_1: None,
option_path_2: Some(PathBuf::from("j.zip")),
},
PathOpt::from_argmatches(&PathOpt::into_app().get_matches_from(&[
PathOpt::parse_from(&[
"test", "-p", "/usr/bin", "-v", "/a/b/c", "-v", "/d/e/f", "-v", "/g/h/i", "-q",
"j.zip",
]))
])
);
}

Expand All @@ -72,23 +72,21 @@ struct HexOpt {
fn test_parse_hex() {
assert_eq!(
HexOpt { number: 5 },
HexOpt::from_argmatches(&HexOpt::into_app().get_matches_from(&["test", "-n", "5"]))
HexOpt::parse_from(&["test", "-n", "5"])
);
assert_eq!(
HexOpt { number: 0xabcdef },
HexOpt::from_argmatches(&HexOpt::into_app().get_matches_from(&["test", "-n", "abcdef"]))
HexOpt::parse_from(&["test", "-n", "abcdef"])
);

let err = HexOpt::into_app()
.get_matches_from_safe(&["test", "-n", "gg"])
.unwrap_err();
let err = HexOpt::try_parse_from(&["test", "-n", "gg"]).unwrap_err();
assert!(err.message.contains("invalid digit found in string"), err);
}

fn custom_parser_1(_: &str) -> &'static str { "A" }
fn custom_parser_2(_: &str) -> Result<&'static str, u32> { Ok("B") }
fn custom_parser_3(_: &OsStr) -> &'static str { "C" }
fn custom_parser_4(_: &OsStr) -> Result<&'static str, OsString> { Ok("D") }
fn custom_parser_4(_: &OsStr) -> Result<&'static str, String> { Ok("D") }

#[derive(Clap, PartialEq, Debug)]
struct NoOpOpt {
Expand All @@ -111,9 +109,7 @@ fn test_every_custom_parser() {
c: "C",
d: "D"
},
NoOpOpt::from_argmatches(
&NoOpOpt::into_app().get_matches_from(&["test", "-a=?", "-b=?", "-c=?", "-d=?"])
)
NoOpOpt::parse_from(&["test", "-a=?", "-b=?", "-c=?", "-d=?"])
);
}

Expand Down Expand Up @@ -141,15 +137,15 @@ fn test_parser_with_default_value() {
integer: 9000,
path: PathBuf::from("src/lib.rs"),
},
DefaultedOpt::from_argmatches(&DefaultedOpt::into_app().get_matches_from(&[
DefaultedOpt::parse_from(&[
"test",
"-b",
"E²=p²c²+m²c⁴",
"-i",
"9000",
"-p",
"src/lib.rs",
]))
])
);
}

Expand All @@ -172,7 +168,11 @@ struct Occurrences {
#[clap(short = "r", parse(from_occurrences))]
little_unsigned: u8,

#[clap(short = "c", long = "custom", parse(from_occurrences = "foo"))]
#[clap(
short = "c",
long = "custom",
parse(from_occurrences = "foo")
)]
custom: Foo,
}

Expand All @@ -186,9 +186,9 @@ fn test_parser_occurrences() {
little_unsigned: 4,
custom: Foo(5),
},
Occurrences::from_argmatches(&Occurrences::into_app().get_matches_from(&[
Occurrences::parse_from(&[
"test", "-s", "--signed", "--signed", "-l", "-rrrr", "-cccc", "--custom",
]))
])
);
}

Expand All @@ -205,25 +205,21 @@ fn test_custom_bool() {
struct Opt {
#[clap(short = "d", parse(try_from_str = "parse_bool"))]
debug: bool,
#[clap(short = "v", default_value = "false", parse(try_from_str = "parse_bool"))]
#[clap(
short = "v",
default_value = "false",
parse(try_from_str = "parse_bool")
)]
verbose: bool,
#[clap(short = "t", parse(try_from_str = "parse_bool"))]
tribool: Option<bool>,
#[clap(short = "b", parse(try_from_str = "parse_bool"))]
bitset: Vec<bool>,
}

assert!(Opt::into_app().get_matches_from_safe(&["test"]).is_err());
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "-d"])
.is_err()
);
assert!(
Opt::into_app()
.get_matches_from_safe(&["test", "-dfoo"])
.is_err()
);
assert!(Opt::try_parse_from(&["test"]).is_err());
assert!(Opt::try_parse_from(&["test", "-d"]).is_err());
assert!(Opt::try_parse_from(&["test", "-dfoo"]).is_err());
assert_eq!(
Opt {
debug: false,
Expand Down
10 changes: 9 additions & 1 deletion tests/doc-comments-help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use clap::Clap;

#[test]
fn commets_intead_of_actual_help() {
use clap::IntoApp;

/// Lorem ipsum
#[derive(Clap, PartialEq, Debug)]
struct LoremIpsum {
Expand All @@ -38,12 +40,17 @@ fn commets_intead_of_actual_help() {

#[test]
fn help_is_better_than_comments() {
use clap::IntoApp;
/// Lorem ipsum
#[derive(Clap, PartialEq, Debug)]
#[clap(name = "lorem-ipsum", about = "Dolor sit amet")]
struct LoremIpsum {
/// Fooify a bar
#[clap(short = "f", long = "foo", help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")]
#[clap(
short = "f",
long = "foo",
help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"
)]
foo: bool,
}

Expand All @@ -58,6 +65,7 @@ fn help_is_better_than_comments() {

#[test]
fn empty_line_in_doc_comment_is_double_linefeed() {
use clap::IntoApp;
/// Foo.
///
/// Bar
Expand Down
Loading

0 comments on commit 2c670d5

Please sign in to comment.