Repository: clap-rs/clap
Pull request #1664 (2020-02-03 16:14:41)

Import structopt
OK, here is about 50% of what's left to import.

`impl StructOpt for Box<impl StructOpt>` is not imported because layouts of `StructOpt` and `Clap` are too different. I'll work it out after the import is done.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/clap-rs/clap/1664)
<!-- Reviewable:end -->



Patch:
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index cd523a41..8abb1158 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -48,11 +48,11 @@ stages:
             displayName: Caching compiled
           - script: rustup default $(rust)-$(target)
             displayName: Install rust
-          - script: cargo test --no-default-features
+          - script: cargo test --all --no-default-features
             displayName: Test without default features
             env:
               RUST_BACKTRACE: full
-          - script: cargo test --features "yaml unstable"
+          - script: cargo test --all --features "yaml unstable"
             displayName: Test with most features
             env:
               RUST_BACKTRACE: full
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index f8912b92..f2d242c8 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -9,8 +9,8 @@ Another really great way to help is if you find an interesting, or helpful way i
 To test with all features both enabled and disabled, you can run these commands:
 
 ```sh
-$ cargo test --no-default-features
-$ cargo test --features "yaml unstable"
+$ cargo test --all --no-default-features
+$ cargo test --all --features "yaml unstable"
 ```
 
 Alternatively, if you have [`just`](https://github.com/casey/just) installed you can run the prebuilt recipes. *Not* using `just` is perfectly fine as well, it simply bundles commands automatically.
@@ -26,7 +26,7 @@ From here on, I will list the appropriate `cargo` command as well as the `just`
 Sometimes it's helpful to only run a subset of the tests, which can be done via:
 
 ```sh
-$ cargo test --test <test_name>
+$ cargo test --all --test <test_name>
 
 # Or
 
@@ -40,8 +40,8 @@ During the CI process `clap` runs against many different lints using [`clippy`](
 In order to check the code for lints and to format it run either:
 
 ```sh
-$ cargo clippy --lib --features "yaml unstable" -- -D warnings
-$ cargo clippy --tests --examples --features "yaml unstable"
+$ cargo clippy --all --lib --features "yaml unstable" -- -D warnings
+$ cargo clippy --all --tests --examples --features "yaml unstable"
 $ cargo fmt -- --check
 
 # Or
@@ -54,10 +54,10 @@ $ just lint
 Another helpful technique is to see the `clap` debug output while developing features. In order to see the debug output while running the full test suite or individual tests, run:
 
 ```sh
-$ cargo test --features debug
+$ cargo test --all --features debug
 
 # Or for individual tests
-$ cargo test --test <test_name> --features debug
+$ cargo test --all --test <test_name> --features debug
 
 # The corresponding just command for individual debugging tests is:
 $ just debug <test_name>
diff --git a/.gitignore b/.gitignore
index fb7ecb01..6a097d46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,8 @@
 *.exe
 
 # Generated by Cargo
-target/
+/target/
+/clap-test/target/
 
 # Cargo files
 Cargo.lock
diff --git a/.travis.yml b/.travis.yml
index 669b59dc..c1425ea9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,8 +43,8 @@ jobs:
         - rustup component add rustfmt
       script:
         - echo "Checking codebase with Clippy release `cargo clippy --version`."
-        - cargo clippy --lib --features "yaml unstable" -- -D warnings
-        - cargo clippy --tests --examples --features "yaml unstable"
+        - cargo clippy --all --lib --features "yaml unstable" -- -D warnings
+        - cargo clippy --all --tests --examples --features "yaml unstable"
         - cargo fmt -- --check
     - rust: nightly
       env:
@@ -66,8 +66,8 @@ jobs:
       script:
         - cargo tarpaulin --workspace --features "yaml unstable" --ciserver travis-ci --coveralls $TRAVIS_JOB_ID
 script:
-  - cargo test --no-default-features
-  - cargo test --features yaml unstable
+  - cargo test --all --no-default-features
+  - cargo test --all --features yaml unstable
 notifications:
   email: false
 env:
diff --git a/Cargo.toml b/Cargo.toml
index d956df5a..db2e040e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,17 +1,31 @@
 [package]
 name = "clap"
 version = "3.0.0-beta.1"
-edition = "2018"
 authors = ["Kevin K. <kbknapp@gmail.com>"]
+exclude = [
+	".github/*",
+	"examples/*",
+	"tests/*",
+	"benches/*",
+	"clap-perf/*",
+	"etc/*",
+	"*.png",
+	"*.dot",
+	"*.yml",
+	"*.toml",
+	"*.md",
+	"clap-test.rs"
+]
 include = [
 	"src/**/*",
 	"Cargo.toml",
 	"README.md"
 ]
-description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
 repository = "https://github.com/clap-rs/clap"
 documentation = "https://docs.rs/clap/"
 homepage = "https://clap.rs/"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
 keywords = [
 	"argument",
 	"cli",
@@ -20,8 +34,10 @@ keywords = [
 	"parse"
 ]
 categories = ["command-line-interface"]
-license = "MIT OR Apache-2.0"
-readme = "README.md"
+description = """
+A simple to use, efficient, and full-featured Command Line Argument Parser
+"""
+edition = "2018"
 
 [badges]
 travis-ci = { repository = "clap-rs/clap", branch = "master" }
@@ -33,14 +49,16 @@ maintenance = {status = "actively-developed"}
 
 [dependencies]
 bitflags              = "1.2"
+exitcode              = "1.1.2"
 unicode-width         = "0.1.4"
 textwrap              = "0.11"
 indexmap              = "1.0.1"
-strsim    = { version = "0.9.0",  optional = true }
-yaml-rust = { version = "0.4.1",  optional = true }
-atty      = { version = "0.2.2",  optional = true }
-vec_map   = { version = "0.8", optional = true }
-term_size = { version = "1.0.0-beta1", optional = true }
+strsim      = { version = "0.9.0",  optional = true }
+yaml-rust   = { version = "0.4.1",  optional = true }
+atty        = { version = "0.2.2",  optional = true }
+vec_map     = { version = "0.8", optional = true }
+term_size   = { version = "1.0.0-beta1", optional = true }
+lazy_static = { version = "1", optional = true }
 clap_derive = { path = "./clap_derive", version = "3.0.0-beta.1", optional = true }
 
 [target.'cfg(not(windows))'.dependencies]
@@ -57,24 +75,36 @@ std         = [] # support for no_std in a backwards-compatible way
 suggestions = ["strsim"]
 color       = ["ansi_term", "atty"]
 wrap_help   = ["term_size", "textwrap/term_size"]
-derive      = ["clap_derive"]
+derive      = ["clap_derive", "lazy_static"]
 yaml        = ["yaml-rust"]
-no_cargo    = [] # Enable if you're not using Cargo, disables Cargo-env-var-dependent macros
 unstable    = [] # for building with unstable clap features (doesn't require nightly Rust) (currently none)
 nightly     = [] # for building with unstable Rust features (currently none)
 debug       = [] # Enables debug messages
+no_cargo    = [] # Enable if you're not using Cargo, disables Cargo-env-var-dependent macros
 doc         = ["yaml"] # All the features which add to documentation
 
 [profile.dev]
+opt-level = 0
+debug = true
+rpath = false
+lto = false
+debug-assertions = true
 codegen-units = 4
 
 [profile.test]
 opt-level = 1
 debug = true
+rpath = false
+lto = false
+debug-assertions = true
 codegen-units = 4
 
 [profile.bench]
+opt-level = 3
+debug = false
+rpath = false
 lto = true
+debug-assertions = false
 codegen-units = 1
 
 [package.metadata.docs.rs]
@@ -84,6 +114,3 @@ features = ["doc"]
 members = [
 	"clap_derive",
 ]
-default-members = [
-	".", "clap_derive",
-]
diff --git a/README.md b/README.md
index ba74f3f2..71e37d9a 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,8 @@ The first example shows the simplest way to use `clap`, by defining a struct. If
 //
 // This example demonstrates clap's full 'custom derive' style of creating arguments which is the
 // simplest method of use, but sacrifices some flexibility.
-use clap::Clap;
+#[macro_use]
+extern crate clap;
 
 /// This doc string acts as a help message when the user runs '--help'
 /// as do all doc strings on fields
@@ -347,7 +348,9 @@ Finally we create our `main.rs` file just like we would have with the previous t
 //
 // This example demonstrates clap's building from YAML style of creating arguments which is far
 // more clean, but takes a very small performance hit compared to the other two methods.
-use clap::{App, load_yaml};
+#[macro_use]
+extern crate clap;
+use clap::App;
 
 fn main() {
     // The YAML file is found relative to the current file, similar to how modules are found
@@ -413,7 +416,9 @@ clap = "3.0.0-beta.1"
 * Add the following to your `src/main.rs`
 
 ```rust
-use clap::{App, Clap};
+#[macro_use]
+extern crate clap;
+use clap::App;
 
 #[derive(Clap)]
 #[clap(version = "v1.0-beta")]
diff --git a/benches/03_complex.rs b/benches/03_complex.rs
index 84bbd7be..afb6ba6b 100644
--- a/benches/03_complex.rs
+++ b/benches/03_complex.rs
@@ -1,8 +1,11 @@
 #![feature(test)]
 
+#[macro_use]
+extern crate clap;
 extern crate test;
 
-use clap::{clap_app, App, AppSettings, Arg, ArgSettings};
+use clap::{App, AppSettings, Arg, ArgSettings};
+
 use test::Bencher;
 
 static OPT3_VALS: [&str; 2] = ["fast", "slow"];
diff --git a/benches/05_ripgrep.rs b/benches/05_ripgrep.rs
index 695da070..3ddd8eb2 100644
--- a/benches/05_ripgrep.rs
+++ b/benches/05_ripgrep.rs
@@ -6,6 +6,8 @@
 #![feature(test)]
 
 extern crate clap;
+#[macro_use]
+extern crate lazy_static;
 extern crate test;
 
 use clap::{App, AppSettings, Arg, ArgSettings};
@@ -14,8 +16,6 @@ use std::collections::HashMap;
 use std::io::Cursor;
 use test::Bencher;
 
-use lazy_static::lazy_static;
-
 #[bench]
 fn build_app_short(b: &mut Bencher) {
     b.iter(app_short);
diff --git a/clap_derive/Cargo.toml b/clap_derive/Cargo.toml
index 489c031d..cfbdf352 100644
--- a/clap_derive/Cargo.toml
+++ b/clap_derive/Cargo.toml
@@ -3,35 +3,18 @@ name = "clap_derive"
 version = "3.0.0-beta.1"
 edition = "2018"
 authors = [
-	"Guillaume Pinot <texitoi@texitoi.eu>",
-	"Kevin K. <kbknapp@gmail.com>",
-	"hoverbear <andrew@hoverbear.org>"
-]
-include = [
-	"src/**/*",
-	"Cargo.toml",
-	"README.md"
+    "Guillaume Pinot <texitoi@texitoi.eu>",
+    "Kevin K. <kbknapp@gmail.com>",
+    "hoverbear <andrew@hoverbear.org>"
 ]
 description = "Parse command line argument by defining a struct, derive crate."
-repository = "https://github.com/clap-rs/clap/tree/master/clap_derive"
 documentation = "https://docs.rs/clap_derive"
-homepage = "https://clap.rs/"
-keywords = [
-	"clap",
-	"cli",
-	"derive",
-	"proc_macro",
-	"parse"
-]
+repository = "https://github.com/clap-rs/clap_derive"
+keywords = ["clap", "cli", "derive", "proc_macro", "parse"]
 categories = ["command-line-interface", "development-tools::procedural-macro-helpers"]
-license = "MIT OR Apache-2.0"
+license = "Apache-2.0/MIT"
 readme = "README.md"
 
-[badges]
-is-it-maintained-issue-resolution = { repository = "clap-rs/clap" }
-is-it-maintained-open-issues = { repository = "clap-rs/clap" }
-maintenance = {status = "actively-developed"}
-
 [lib]
 proc-macro = true
 
@@ -49,10 +32,7 @@ rustversion = "1"
 
 [features]
 default = []
-unstable = []
 nightly = []
+lints = []
 debug = []
 doc = []
-
-[package.metadata.docs.rs]
-features = ["doc"]
diff --git a/clap_derive/src/derives/attrs.rs b/clap_derive/src/derives/attrs.rs
index 9d35bbe4..6c6b7aea 100644
--- a/clap_derive/src/derives/attrs.rs
+++ b/clap_derive/src/derives/attrs.rs
@@ -12,26 +12,29 @@
 // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
 // MIT/Apache 2.0 license.
 
-use super::{parse::*, spanned::Sp, ty::Ty};
+use super::{doc_comments::process_doc_comment, parse::*, spanned::Sp, ty::Ty};
 
 use std::env;
 
 use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase};
-use proc_macro2::{self, Span};
+use proc_macro2::{self, Span, TokenStream};
 use proc_macro_error::abort;
 use quote::{quote, quote_spanned, ToTokens};
-use syn::{self, ext::IdentExt, spanned::Spanned, LitStr};
+use syn::{self, ext::IdentExt, spanned::Spanned, Expr, Ident, MetaNameValue, Type};
 
 /// Default casing style for generated arguments.
 pub const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;
 
+/// Default casing style for environment variables
+pub const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake;
+
 #[allow(clippy::large_enum_variant)]
 #[derive(Clone)]
 pub enum Kind {
     Arg(Sp<Ty>),
     Subcommand(Sp<Ty>),
-    FlattenStruct,
-    Skip(Option<syn::Expr>),
+    Flatten,
+    Skip(Option<Expr>),
 }
 
 #[derive(Clone)]
@@ -75,20 +78,24 @@ pub enum CasingStyle {
 
 #[derive(Clone)]
 pub enum Name {
-    Derived(syn::Ident),
-    Assigned(syn::LitStr),
+    Derived(Ident),
+    Assigned(TokenStream),
 }
 
 #[derive(Clone)]
 pub struct Attrs {
     name: Name,
     casing: Sp<CasingStyle>,
+    env_casing: Sp<CasingStyle>,
+    ty: Option<Type>,
+    doc_comment: Vec<Method>,
     methods: Vec<Method>,
     parser: Sp<Parser>,
     author: Option<Method>,
     about: Option<Method>,
     version: Option<Method>,
-    no_version: Option<syn::Ident>,
+    no_version: Option<Ident>,
+    verbatim_doc_comment: Option<Ident>,
     has_custom_parser: bool,
     kind: Sp<Kind>,
 }
@@ -104,7 +111,7 @@ pub struct GenOutput {
 }
 
 impl Method {
-    fn new(name: syn::Ident, args: proc_macro2::TokenStream) -> Self {
+    pub fn new(name: Ident, args: TokenStream) -> Self {
         Method { name, args }
     }
 
@@ -213,11 +220,11 @@ impl CasingStyle {
 }
 
 impl Name {
-    pub fn translate(self, style: CasingStyle) -> LitStr {
-        use self::CasingStyle::*;
+    pub fn translate(self, style: CasingStyle) -> TokenStream {
+        use CasingStyle::*;
 
         match self {
-            Name::Assigned(lit) => lit,
+            Name::Assigned(tokens) => tokens,
             Name::Derived(ident) => {
                 let s = ident.unraw().to_string();
                 let s = match style {
@@ -228,38 +235,46 @@ impl Name {
                     Snake => s.to_snake_case(),
                     Verbatim => s,
                 };
-                syn::LitStr::new(&s, ident.span())
+                quote_spanned!(ident.span()=> #s)
             }
         }
     }
 }
 
 impl Attrs {
-    fn new(default_span: Span, name: Name, casing: Sp<CasingStyle>) -> Self {
+    fn new(
+        default_span: Span,
+        name: Name,
+        ty: Option<Type>,
+        casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
+    ) -> Self {
         Self {
             name,
+            ty,
             casing,
+            env_casing,
+            doc_comment: vec![],
             methods: vec![],
             parser: Parser::default_spanned(default_span),
             about: None,
             author: None,
             version: None,
             no_version: None,
+            verbatim_doc_comment: None,
 
             has_custom_parser: false,
             kind: Sp::new(Kind::Arg(Sp::new(Ty::Other, default_span)), default_span),
         }
     }
 
-    /// push `.method("str literal")`
-    fn push_str_method(&mut self, name: Sp<String>, arg: Sp<String>) {
-        match (&**name, &**arg) {
-            ("name", _) => {
-                self.name = Name::Assigned(arg.as_lit());
-            }
-            _ => self
-                .methods
-                .push(Method::new(name.as_ident(), quote!(#arg))),
+    fn push_method(&mut self, name: Ident, arg: impl ToTokens) {
+        if name == "name" {
+            self.name = Name::Assigned(quote!(#arg));
+        } else if name == "version" {
+            self.version = Some(Method::new(name, quote!(#arg)));
+        } else {
+            self.methods.push(Method::new(name, quote!(#arg)))
         }
     }
 
@@ -269,10 +284,11 @@ impl Attrs {
         for attr in parse_clap_attributes(attrs) {
             match attr {
                 Short(ident) | Long(ident) => {
-                    self.push_str_method(
-                        ident.into(),
-                        self.name.clone().translate(*self.casing).into(),
-                    );
+                    self.push_method(ident, self.name.clone().translate(*self.casing));
+                }
+
+                Env(ident) => {
+                    self.push_method(ident, self.name.clone().translate(*self.env_casing));
                 }
 
                 Subcommand(ident) => {
@@ -282,7 +298,7 @@ impl Attrs {
                 }
 
                 Flatten(ident) => {
-                    let kind = Sp::new(Kind::FlattenStruct, ident.span());
+                    let kind = Sp::new(Kind::Flatten, ident.span());
                     self.set_kind(kind);
                 }
 
@@ -293,6 +309,39 @@ impl Attrs {
 
                 NoVersion(ident) => self.no_version = Some(ident),
 
+                VerbatimDocComment(ident) => self.verbatim_doc_comment = Some(ident),
+
+                DefaultValue(ident, lit) => {
+                    let val = if let Some(lit) = lit {
+                        quote!(#lit)
+                    } else {
+                        let ty = if let Some(ty) = self.ty.as_ref() {
+                            ty
+                        } else {
+                            abort!(
+                                ident.span(),
+                                "#[structopt(default_value)] (without an argument) can be used \
+                                only on field level";
+
+                                note = "see \
+                                    https://docs.rs/structopt/0.3.5/structopt/#magical-methods")
+                        };
+
+                        quote_spanned!(ident.span()=> {
+                            ::clap::lazy_static::lazy_static! {
+                                static ref DEFAULT_VALUE: &'static str = {
+                                    let val = <#ty as ::std::default::Default>::default();
+                                    let s = ::std::string::ToString::to_string(&val);
+                                    ::std::boxed::Box::leak(s.into_boxed_str())
+                                };
+                            }
+                            *DEFAULT_VALUE
+                        })
+                    };
+
+                    self.methods.push(Method::new(ident, val));
+                }
+
                 About(ident, about) => {
                     self.about = Method::from_lit_or_env(ident, about, "CARGO_PKG_DESCRIPTION");
                 }
@@ -302,21 +351,27 @@ impl Attrs {
                 }
 
                 Version(ident, version) => {
-                    self.version = Some(Method::new(ident, quote!(#version)))
+                    self.push_method(ident, version);
                 }
 
                 NameLitStr(name, lit) => {
-                    self.push_str_method(name.into(), lit.into());
+                    self.push_method(name, lit);
                 }
 
-                NameExpr(name, expr) => self.methods.push(Method::new(name, quote!(#expr))),
+                NameExpr(name, expr) => {
+                    self.push_method(name, expr);
+                }
 
-                MethodCall(name, args) => self.methods.push(Method::new(name, quote!(#(#args),*))),
+                MethodCall(name, args) => self.push_method(name, quote!(#(#args),*)),
 
                 RenameAll(_, casing_lit) => {
                     self.casing = CasingStyle::from_lit(casing_lit);
                 }
 
+                RenameAllEnv(_, casing_lit) => {
+                    self.env_casing = CasingStyle::from_lit(casing_lit);
+                }
+
                 Parse(ident, spec) => {
                     self.has_custom_parser = true;
                     self.parser = Parser::from_spec(ident, spec);
@@ -326,85 +381,25 @@ impl Attrs {
     }
 
     fn push_doc_comment(&mut self, attrs: &[syn::Attribute], name: &str) {
-        let doc_comments = attrs
+        use syn::Lit::*;
+        use syn::Meta::*;
+
+        let comment_parts: Vec<_> = attrs
             .iter()
+            .filter(|attr| attr.path.is_ident("doc"))
             .filter_map(|attr| {
-                if attr.path.is_ident("doc") {
-                    attr.parse_meta().ok()
+                if let Ok(NameValue(MetaNameValue { lit: Str(s), .. })) = attr.parse_meta() {
+                    Some(s.value())
                 } else {
+                    // non #[doc = "..."] attributes are not our concern
+                    // we leave them for rustc to handle
                     None
                 }
             })
-            .filter_map(|attr| {
-                use syn::Lit::*;
-                use syn::Meta::*;
-                if let NameValue(syn::MetaNameValue {
-                    path, lit: Str(s), ..
-                }) = attr
-                {
-                    if !path.is_ident("doc") {
-                        return None;
-                    }
-                    let value = s.value();
-
-                    let text = value
-                        .trim_start_matches("//!")
-                        .trim_start_matches("///")
-                        .trim_start_matches("/*!")
-                        .trim_start_matches("/**")
-                        .trim_end_matches("*/")
-                        .trim();
-                    if text.is_empty() {
-                        Some("\n\n".to_string())
-                    } else {
-                        Some(text.to_string())
-                    }
-                } else {
-                    None
-                }
-            })
-            .collect::<Vec<_>>();
-        if doc_comments.is_empty() {
-            return;
-        }
-        let merged_lines = doc_comments
-            .join(" ")
-            .split('\n')
-            .map(str::trim)
-            .map(str::to_string)
-            .collect::<Vec<_>>()
-            .join("\n");
-
-        let expected_doc_comment_split = if let Some(content) = doc_comments.get(1) {
-            (doc_comments.len() > 2) && (content == "\n\n")
-        } else {
-            false
-        };
-
-        if expected_doc_comment_split {
-            let long_name = Sp::call_site(format!("long_{}", name));
+            .collect();
 
-            self.methods
-                .push(Method::new(long_name.as_ident(), quote!(#merged_lines)));
-
-            // Remove trailing whitespace and period from short help, as rustdoc
-            // best practice is to use complete sentences, but command-line help
-            // typically omits the trailing period.
-            let short_arg = doc_comments
-                .first()
-                .map(|s| s.trim())
-                .map_or("", |s| s.trim_end_matches('.'));
-
-            self.methods.push(Method::new(
-                syn::Ident::new(name, Span::call_site()),
-                quote!(#short_arg),
-            ));
-        } else {
-            self.methods.push(Method::new(
-                syn::Ident::new(name, Span::call_site()),
-                quote!(#merged_lines),
-            ));
-        }
+        self.doc_comment =
+            process_doc_comment(comment_parts, name, self.verbatim_doc_comment.is_none());
     }
 
     pub fn from_struct(
@@ -412,8 +407,9 @@ impl Attrs {
         attrs: &[syn::Attribute],
         name: Name,
         argument_casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
     ) -> Self {
-        let mut res = Self::new(span, name, argument_casing);
+        let mut res = Self::new(span, name, None, argument_casing, env_casing);
         res.push_attrs(attrs);
         res.push_doc_comment(attrs, "about");
 
@@ -425,20 +421,29 @@ impl Attrs {
         }
         match &*res.kind {
             Kind::Subcommand(_) => abort!(res.kind.span(), "subcommand is only allowed on fields"),
-            Kind::FlattenStruct => abort!(res.kind.span(), "flatten is only allowed on fields"),
             Kind::Skip(_) => abort!(res.kind.span(), "skip is only allowed on fields"),
-            Kind::Arg(_) => res,
+            Kind::Arg(_) | Kind::Flatten => res,
         }
     }
 
-    pub fn from_field(field: &syn::Field, struct_casing: Sp<CasingStyle>) -> Self {
+    pub fn from_field(
+        field: &syn::Field,
+        struct_casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
+    ) -> Self {
         let name = field.ident.clone().unwrap();
-        let mut res = Self::new(field.span(), Name::Derived(name), struct_casing);
-        res.push_doc_comment(&field.attrs, "help");
+        let mut res = Self::new(
+            field.span(),
+            Name::Derived(name),
+            Some(field.ty.clone()),
+            struct_casing,
+            env_casing,
+        );
         res.push_attrs(&field.attrs);
+        res.push_doc_comment(&field.attrs, "help");
 
         match &*res.kind {
-            Kind::FlattenStruct => {
+            Kind::Flatten => {
                 if res.has_custom_parser {
                     abort!(
                         res.parser.span(),
@@ -574,36 +579,35 @@ impl Attrs {
     }
 
     /// generate methods from attributes on top of struct or enum
-    pub fn top_level_methods(&self) -> proc_macro2::TokenStream {
-        let version = match (&self.no_version, &self.version) {
-            (Some(no_version), Some(_)) => abort!(
-                no_version.span(),
-                "`no_version` and `version = \"version\"` can't be used together"
-            ),
-
-            (None, Some(m)) => m.to_token_stream(),
-
-            (None, None) => std::env::var("CARGO_PKG_VERSION")
-                .map(|version| quote!( .version(#version) ))
-                .unwrap_or_default(),
-
-            (Some(_), None) => quote!(),
-        };
-
+    pub fn top_level_methods(&self) -> TokenStream {
         let author = &self.author;
         let about = &self.about;
         let methods = &self.methods;
+        let doc_comment = &self.doc_comment;
 
-        quote!( #author #version #(#methods)* #about )
+        quote!( #(#doc_comment)* #author #about #(#methods)*  )
     }
 
     /// generate methods on top of a field
     pub fn field_methods(&self) -> proc_macro2::TokenStream {
         let methods = &self.methods;
-        quote!( #(#methods)* )
+        let doc_comment = &self.doc_comment;
+        quote!( #(#doc_comment)* #(#methods)* )
     }
 
-    pub fn cased_name(&self) -> LitStr {
+    pub fn version(&self) -> TokenStream {
+        match (&self.no_version, &self.version) {
+            (None, Some(m)) => m.to_token_stream(),
+
+            (None, None) => std::env::var("CARGO_PKG_VERSION")
+                .map(|version| quote!( .version(#version) ))
+                .unwrap_or_default(),
+
+            _ => quote!(),
+        }
+    }
+
+    pub fn cased_name(&self) -> TokenStream {
         self.name.clone().translate(*self.casing)
     }
 
@@ -619,6 +623,10 @@ impl Attrs {
         self.casing.clone()
     }
 
+    pub fn env_casing(&self) -> Sp<CasingStyle> {
+        self.env_casing.clone()
+    }
+
     pub fn is_positional(&self) -> bool {
         self.methods
             .iter()
@@ -632,9 +640,13 @@ impl Attrs {
     }
 
     pub fn has_doc_methods(&self) -> bool {
-        self.methods
-            .iter()
-            .any(|m| m.name == "help" || m.name == "long_help")
+        !self.doc_comment.is_empty()
+            || self.methods.iter().any(|m| {
+                m.name == "help"
+                    || m.name == "long_help"
+                    || m.name == "about"
+                    || m.name == "long_about"
+            })
     }
 }
 
diff --git a/clap_derive/src/derives/clap.rs b/clap_derive/src/derives/clap.rs
index 9d0cd267..0367dcf5 100644
--- a/clap_derive/src/derives/clap.rs
+++ b/clap_derive/src/derives/clap.rs
@@ -11,9 +11,9 @@
 // This work was derived from Structopt (https://github.com/TeXitoi/structopt)
 // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
 // MIT/Apache 2.0 license.
-use proc_macro2;
+use proc_macro2::Span;
 use proc_macro_error::{abort, abort_call_site, set_dummy};
-use syn::{self, punctuated, spanned::Spanned, token};
+use syn::{self, punctuated, spanned::Spanned, token, FieldsUnnamed, Ident};
 
 use super::{from_argmatches, into_app, sub_type, Attrs, Kind, Name, ParserKind, Ty};
 
@@ -25,7 +25,11 @@ fn gen_app_augmentation(
     parent_attribute: &Attrs,
 ) -> proc_macro2::TokenStream {
     let mut subcmds = fields.iter().filter_map(|field| {
-        let attrs = Attrs::from_field(&field, parent_attribute.casing());
+        let attrs = Attrs::from_field(
+            &field,
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
         let kind = attrs.kind();
         if let Kind::Subcommand(ty) = &*kind {
             let subcmd_type = match (**ty, sub_type(&field.ty)) {
@@ -61,11 +65,15 @@ fn gen_app_augmentation(
     }
 
     let args = fields.iter().filter_map(|field| {
-        let attrs = Attrs::from_field(field, parent_attribute.casing());
+        let attrs = Attrs::from_field(
+            field,
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
         let kind = attrs.kind();
         match &*kind {
             Kind::Subcommand(_) | Kind::Skip(_) => None,
-            Kind::FlattenStruct => {
+            Kind::Flatten => {
                 let ty = &field.ty;
                 Some(quote_spanned! { kind.span()=>
                     let #app_var = <#ty>::augment_app(#app_var);
@@ -167,11 +175,12 @@ fn gen_app_augmentation(
     });
 
     let app_methods = parent_attribute.top_level_methods();
+    let version = parent_attribute.version();
     quote! {{
         let #app_var = #app_var#app_methods;
         #( #args )*
         #subcmd
-        #app_var
+        #app_var#version
     }}
 }
 
@@ -202,48 +211,73 @@ fn gen_augment_app_for_enum(
             &variant.attrs,
             Name::Derived(variant.ident.clone()),
             parent_attribute.casing(),
+            parent_attribute.env_casing(),
         );
-        let app_var = syn::Ident::new("subcommand", proc_macro2::Span::call_site());
-        let arg_block = match variant.fields {
-            Named(ref fields) => gen_app_augmentation(&fields.named, &app_var, &attrs),
-            Unit => quote!( #app_var ),
-            Unnamed(syn::FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
-                let ty = &unnamed[0];
-                quote_spanned! { ty.span() =>
-                    {
-                        let #app_var = <#ty>::augment_app(#app_var);
-                        if <#ty>::is_subcommand() {
-                            #app_var.setting(
-                                ::clap::AppSettings::SubcommandRequiredElseHelp
-                            )
-                        } else {
-                            #app_var
+        let kind = attrs.kind();
+        match &*kind {
+            Kind::Flatten => match variant.fields {
+                Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
+                    let ty = &unnamed[0];
+                    quote! {
+                        let app = <#ty>::augment_app(app);
+                    }
+                }
+                _ => abort!(
+                    variant.span(),
+                    "`flatten` is usable only with single-typed tuple variants"
+                ),
+            },
+            _ => {
+                let app_var = Ident::new("subcommand", Span::call_site());
+                let arg_block = match variant.fields {
+                    Named(ref fields) => gen_app_augmentation(&fields.named, &app_var, &attrs),
+                    Unit => quote!( #app_var ),
+                    Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
+                        let ty = &unnamed[0];
+                        quote_spanned! { ty.span()=>
+                            {
+                                let #app_var = <#ty>::augment_app(
+                                    #app_var
+                                );
+                                if <#ty>::is_subcommand() {
+                                    #app_var.setting(
+                                        ::clap::AppSettings::SubcommandRequiredElseHelp
+                                    )
+                                } else {
+                                    #app_var
+                                }
+                            }
                         }
                     }
+                    Unnamed(..) => abort!(
+                        variant.span(),
+                        "non single-typed tuple enums are not supported"
+                    ),
+                };
+
+                let name = attrs.cased_name();
+                let from_attrs = attrs.top_level_methods();
+                let version = attrs.version();
+                quote! {
+                    let app = app.subcommand({
+                        let #app_var = ::clap::App::new(#name);
+                        let #app_var = #arg_block;
+                        #app_var#from_attrs#version
+                    });
                 }
             }
-            Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident),
-        };
-
-        let name = attrs.cased_name();
-        let from_attrs = attrs.top_level_methods();
-
-        quote! {
-            .subcommand({
-                let #app_var = ::clap::App::new(#name);
-                let #app_var = #arg_block;
-                #app_var#from_attrs
-            })
         }
     });
 
     let app_methods = parent_attribute.top_level_methods();
-
+    let version = parent_attribute.version();
     quote! {
-        pub fn augment_app<'b>(
+       pub fn augment_app<'b>(
             app: ::clap::App<'b>
         ) -> ::clap::App<'b> {
-            app #app_methods #( #subcommands )*
+            let app = app #app_methods;
+            #( #subcommands )*;
+            app #version
         }
     }
 }
@@ -254,14 +288,27 @@ fn gen_from_subcommand(
     parent_attribute: &Attrs,
 ) -> proc_macro2::TokenStream {
     use syn::Fields::*;
+    let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
+        .iter()
+        .map(|variant| {
+            let attrs = Attrs::from_struct(
+                variant.span(),
+                &variant.attrs,
+                Name::Derived(variant.ident.clone()),
+                parent_attribute.casing(),
+                parent_attribute.env_casing(),
+            );
+            (variant, attrs)
+        })
+        .partition(|(_, attrs)| {
+            let kind = attrs.kind();
+            match &*kind {
+                Kind::Flatten => true,
+                _ => false,
+            }
+        });
 
-    let match_arms = variants.iter().map(|variant| {
-        let attrs = Attrs::from_struct(
-            variant.span(),
-            &variant.attrs,
-            Name::Derived(variant.ident.clone()),
-            parent_attribute.casing(),
-        );
+    let match_arms = variants.iter().map(|(variant, attrs)| {
         let sub_name = attrs.cased_name();
         let variant_name = &variant.ident;
         let constructor_block = match variant.fields {
@@ -275,8 +322,26 @@ fn gen_from_subcommand(
         };
 
         quote! {
-            (#sub_name, Some(matches)) =>
+            (#sub_name, Some(matches)) => {
                 Some(#name :: #variant_name #constructor_block)
+            }
+        }
+    });
+    let child_subcommands = flatten_variants.iter().map(|(variant, _attrs)| {
+        let variant_name = &variant.ident;
+        match variant.fields {
+            Unnamed(ref fields) if fields.unnamed.len() == 1 => {
+                let ty = &fields.unnamed[0];
+                quote! {
+                    if let Some(res) = <#ty>::from_subcommand(other) {
+                        return Some(#name :: #variant_name (res));
+                    }
+                }
+            }
+            _ => abort!(
+                variant.span(),
+                "`flatten` is usable only with single-typed tuple variants"
+            ),
         }
     });
 
@@ -286,7 +351,10 @@ fn gen_from_subcommand(
         ) -> Option<Self> {
             match sub {
                 #( #match_arms ),*,
-                _ => None
+                other => {
+                    #( #child_subcommands )*;
+                    None
+                }
             }
         }
     }
@@ -379,7 +447,7 @@ pub fn derive_clap(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
         }
 
         impl #struct_name {
-            fn parse() -> Self {
+           pub fn parse() -> Self {
                 unimplemented!();
             }
         }
diff --git a/clap_derive/src/derives/doc_comments.rs b/clap_derive/src/derives/doc_comments.rs
new file mode 100644
index 00000000..338e6179
--- /dev/null
+++ b/clap_derive/src/derives/doc_comments.rs
@@ -0,0 +1,103 @@
+//! The preprocessing we apply to doc comments.
+//!
+//! structopt works in terms of "paragraphs". Paragraph is a sequence of
+//! non-empty adjacent lines, delimited by sequences of blank (whitespace only) lines.
+
+use super::attrs::Method;
+use quote::{format_ident, quote};
+use std::iter;
+
+pub fn process_doc_comment(lines: Vec<String>, name: &str, preprocess: bool) -> Vec<Method> {
+    // multiline comments (`/** ... */`) may have LFs (`\n`) in them,
+    // we need to split so we could handle the lines correctly
+    //
+    // we also need to remove leading and trailing blank lines
+    let mut lines: Vec<&str> = lines
+        .iter()
+        .skip_while(|s| is_blank(s))
+        .flat_map(|s| s.split('\n'))
+        .collect();
+
+    while let Some(true) = lines.last().map(|s| is_blank(s)) {
+        lines.pop();
+    }
+
+    // remove one leading space no matter what
+    for line in lines.iter_mut() {
+        if line.starts_with(' ') {
+            *line = &line[1..];
+        }
+    }
+
+    if lines.is_empty() {
+        return vec![];
+    }
+
+    let short_name = format_ident!("{}", name);
+    let long_name = format_ident!("long_{}", name);
+
+    if let Some(first_blank) = lines.iter().position(|s| is_blank(s)) {
+        let (short, long) = if preprocess {
+            let paragraphs = split_paragraphs(&lines);
+            let short = paragraphs[0].clone();
+            let long = paragraphs.join("\n\n");
+            (remove_period(short), long)
+        } else {
+            let short = lines[..first_blank].join("\n");
+            let long = lines.join("\n");
+            (short, long)
+        };
+
+        vec![
+            Method::new(short_name, quote!(#short)),
+            Method::new(long_name, quote!(#long)),
+        ]
+    } else {
+        let short = if preprocess {
+            let s = merge_lines(&lines);
+            remove_period(s)
+        } else {
+            lines.join("\n")
+        };
+
+        vec![Method::new(short_name, quote!(#short))]
+    }
+}
+
+fn split_paragraphs(lines: &[&str]) -> Vec<String> {
+    let mut last_line = 0;
+    iter::from_fn(|| {
+        let slice = &lines[last_line..];
+        let start = slice.iter().position(|s| !is_blank(s)).unwrap_or(0);
+
+        let slice = &slice[start..];
+        let len = slice
+            .iter()
+            .position(|s| is_blank(s))
+            .unwrap_or_else(|| slice.len());
+
+        last_line += start + len;
+
+        if len != 0 {
+            Some(merge_lines(&slice[..len]))
+        } else {
+            None
+        }
+    })
+    .collect()
+}
+
+fn remove_period(mut s: String) -> String {
+    if s.ends_with('.') && !s.ends_with("..") {
+        s.pop();
+    }
+    s
+}
+
+fn is_blank(s: &str) -> bool {
+    s.trim().is_empty()
+}
+
+fn merge_lines(lines: &[&str]) -> String {
+    lines.iter().map(|s| s.trim()).collect::<Vec<_>>().join(" ")
+}
diff --git a/clap_derive/src/derives/from_argmatches.rs b/clap_derive/src/derives/from_argmatches.rs
index 963b6ac4..057e638b 100644
--- a/clap_derive/src/derives/from_argmatches.rs
+++ b/clap_derive/src/derives/from_argmatches.rs
@@ -19,7 +19,9 @@ use syn::punctuated;
 use syn::spanned::Spanned as _;
 use syn::token;
 
-use super::{spanned::Sp, sub_type, Attrs, Kind, Name, ParserKind, Ty, DEFAULT_CASING};
+use super::{
+    spanned::Sp, sub_type, Attrs, Kind, Name, ParserKind, Ty, DEFAULT_CASING, DEFAULT_ENV_CASING,
+};
 
 pub fn derive_from_argmatches(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
     use syn::Data::*;
@@ -37,8 +39,9 @@ pub fn derive_from_argmatches(input: &syn::DeriveInput) -> proc_macro2::TokenStr
             let attrs = Attrs::from_struct(
                 proc_macro2::Span::call_site(),
                 &input.attrs,
-                Name::Assigned(syn::LitStr::new(&name, proc_macro2::Span::call_site())),
+                Name::Assigned(quote!(#name)),
                 Sp::call_site(DEFAULT_CASING),
+                Sp::call_site(DEFAULT_ENV_CASING),
             );
 
             gen_from_argmatches_impl_for_struct(struct_name, &fields.named, &attrs)
@@ -92,7 +95,11 @@ pub fn gen_constructor(
     parent_attribute: &Attrs,
 ) -> proc_macro2::TokenStream {
     let fields = fields.iter().map(|field| {
-        let attrs = Attrs::from_field(field, parent_attribute.casing());
+        let attrs = Attrs::from_field(
+            field,
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
         let field_name = field.ident.as_ref().unwrap();
         let kind = attrs.kind();
         match &*attrs.kind() {
@@ -110,7 +117,7 @@ pub fn gen_constructor(
                 }
             }
 
-            Kind::FlattenStruct => quote_spanned! { kind.span()=>
+            Kind::Flatten => quote_spanned! { kind.span()=>
                 #field_name: ::clap::FromArgMatches::from_argmatches(matches)
             },
 
diff --git a/clap_derive/src/derives/into_app.rs b/clap_derive/src/derives/into_app.rs
index 31e2b57e..16b3c397 100644
--- a/clap_derive/src/derives/into_app.rs
+++ b/clap_derive/src/derives/into_app.rs
@@ -16,7 +16,7 @@ use std::env;
 use proc_macro2;
 use syn;
 
-use super::{spanned::Sp, Attrs, GenOutput, Name, DEFAULT_CASING};
+use super::{spanned::Sp, Attrs, GenOutput, Name, DEFAULT_CASING, DEFAULT_ENV_CASING};
 
 pub fn derive_into_app(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
     use syn::Data::*;
@@ -79,8 +79,9 @@ pub fn gen_app_builder(attrs: &[syn::Attribute]) -> GenOutput {
     let attrs = Attrs::from_struct(
         proc_macro2::Span::call_site(),
         attrs,
-        Name::Assigned(syn::LitStr::new(&name, proc_macro2::Span::call_site())),
+        Name::Assigned(quote!(#name)),
         Sp::call_site(DEFAULT_CASING),
+        Sp::call_site(DEFAULT_ENV_CASING),
     );
     let tokens = {
         let name = attrs.cased_name();
diff --git a/clap_derive/src/derives/mod.rs b/clap_derive/src/derives/mod.rs
index a73e2389..ad411238 100644
--- a/clap_derive/src/derives/mod.rs
+++ b/clap_derive/src/derives/mod.rs
@@ -14,6 +14,7 @@
 pub mod arg_enum;
 pub mod attrs;
 mod clap;
+mod doc_comments;
 mod from_argmatches;
 mod into_app;
 pub mod parse;
@@ -23,6 +24,7 @@ pub mod ty;
 // pub use self::arg_enum::derive_arg_enum;
 pub use self::attrs::{
     Attrs, CasingStyle, GenOutput, Kind, Name, Parser, ParserKind, DEFAULT_CASING,
+    DEFAULT_ENV_CASING,
 };
 pub use self::clap::derive_clap;
 pub use self::from_argmatches::derive_from_argmatches;
diff --git a/clap_derive/src/derives/parse.rs b/clap_derive/src/derives/parse.rs
index a0bb41c8..62caeec8 100644
--- a/clap_derive/src/derives/parse.rs
+++ b/clap_derive/src/derives/parse.rs
@@ -1,46 +1,34 @@
 use std::iter::FromIterator;
 
-use proc_macro2::TokenStream;
 use proc_macro_error::{abort, ResultExt};
+use quote::ToTokens;
 use syn::{
     self, parenthesized,
     parse::{Parse, ParseBuffer, ParseStream},
-    parse2,
     punctuated::Punctuated,
     spanned::Spanned,
     Attribute, Expr, ExprLit, Ident, Lit, LitBool, LitStr, Token,
 };
 
-pub struct ClapAttributes {
-    pub paren_token: syn::token::Paren,
-    pub attrs: Punctuated<ClapAttr, Token![,]>,
-}
-
-impl Parse for ClapAttributes {
-    fn parse(input: ParseStream) -> syn::Result<Self> {
-        let content;
-        let paren_token = parenthesized!(content in input);
-        let attrs = content.parse_terminated(ClapAttr::parse)?;
-
-        Ok(ClapAttributes { paren_token, attrs })
-    }
-}
-
 #[allow(clippy::large_enum_variant)]
 pub enum ClapAttr {
     // single-identifier attributes
     Short(Ident),
     Long(Ident),
+    Env(Ident),
     Flatten(Ident),
     Subcommand(Ident),
     NoVersion(Ident),
+    VerbatimDocComment(Ident),
 
     // ident [= "string literal"]
     About(Ident, Option<LitStr>),
     Author(Ident, Option<LitStr>),
+    DefaultValue(Ident, Option<LitStr>),
 
     // ident = "string literal"
     Version(Ident, LitStr),
+    RenameAllEnv(Ident, LitStr),
     RenameAll(Ident, LitStr),
     NameLitStr(Ident, LitStr),
 
@@ -85,6 +73,8 @@ impl Parse for ClapAttr {
 
                 match &*name_str {
                     "rename_all" => Ok(RenameAll(name, lit)),
+                    "rename_all_env" => Ok(RenameAllEnv(name, lit)),
+                    "default_value" => Ok(DefaultValue(name, Some(lit))),
 
                     "version" => {
                         check_empty_lit("version");
@@ -177,10 +167,13 @@ impl Parse for ClapAttr {
             match name_str.as_ref() {
                 "long" => Ok(Long(name)),
                 "short" => Ok(Short(name)),
+                "env" => Ok(Env(name)),
                 "flatten" => Ok(Flatten(name)),
                 "subcommand" => Ok(Subcommand(name)),
                 "no_version" => Ok(NoVersion(name)),
+                "verbatim_doc_comment" => Ok(VerbatimDocComment(name)),
 
+                "default_value" => Ok(DefaultValue(name, None)),
                 "about" => (Ok(About(name, None))),
                 "author" => (Ok(Author(name, None))),
 
@@ -225,18 +218,39 @@ impl Parse for ParserSpec {
 }
 
 fn raw_method_suggestion(ts: ParseBuffer) -> String {
-    let do_parse = move || -> Result<(Ident, TokenStream), syn::Error> {
+    let do_parse = move || -> Result<(Ident, Punctuated<Expr, Token![,]>), syn::Error> {
         let name = ts.parse()?;
         let _eq: Token![=] = ts.parse()?;
         let val: LitStr = ts.parse()?;
-        Ok((name, syn::parse_str(&val.value())?))
+        let exprs = val.parse_with(Punctuated::<Expr, Token![,]>::parse_terminated)?;
+        Ok((name, exprs))
     };
-    if let Ok((name, val)) = do_parse() {
-        let val = val.to_string().replace(" ", "").replace(",", ", ");
+
+    fn to_string<T: ToTokens>(val: &T) -> String {
+        val.to_token_stream()
+            .to_string()
+            .replace(" ", "")
+            .replace(",", ", ")
+    }
+
+    if let Ok((name, exprs)) = do_parse() {
+        let suggestion = if exprs.len() == 1 {
+            let val = to_string(&exprs[0]);
+            format!(" = {}", val)
+        } else {
+            let val = exprs
+                .into_iter()
+                .map(|expr| to_string(&expr))
+                .collect::<Vec<_>>()
+                .join(", ");
+
+            format!("({})", val)
+        };
+
         format!(
             "if you need to call `clap::Arg/App::{}` method you \
-             can do it like this: #[clap({}({}))]",
-            name, name, val
+             can do it like this: #[clap({}{})]",
+            name, name, suggestion
         )
     } else {
         "if you need to call some method from `clap::Arg/App` \
@@ -251,19 +265,8 @@ pub fn parse_clap_attributes(all_attrs: &[Attribute]) -> Vec<ClapAttr> {
         .iter()
         .filter(|attr| attr.path.is_ident("clap"))
         .flat_map(|attr| {
-            let attrs: ClapAttributes = parse2(attr.tokens.clone())
-                .map_err(|e| match &*e.to_string() {
-                    // this error message is misleading and points to Span::call_site()
-                    // so we patch it with something meaningful
-                    "unexpected end of input, expected parentheses" => {
-                        let span = attr.path.span();
-                        let patch_msg = "expected parentheses after `clap`";
-                        syn::Error::new(span, patch_msg)
-                    }
-                    _ => e,
-                })
-                .unwrap_or_abort();
-            attrs.attrs
+            attr.parse_args_with(Punctuated::<ClapAttr, Token![,]>::parse_terminated)
+                .unwrap_or_abort()
         })
         .collect()
 }
diff --git a/clap_derive/src/derives/spanned.rs b/clap_derive/src/derives/spanned.rs
index 4eacfad7..8abe3052 100644
--- a/clap_derive/src/derives/spanned.rs
+++ b/clap_derive/src/derives/spanned.rs
@@ -27,16 +27,6 @@ impl<T> Sp<T> {
     }
 }
 
-impl<T: ToString> Sp<T> {
-    pub fn as_ident(&self) -> Ident {
-        Ident::new(&self.to_string(), self.span)
-    }
-
-    pub fn as_lit(&self) -> LitStr {
-        LitStr::new(&self.to_string(), self.span)
-    }
-}
-
 impl<T> Deref for Sp<T> {
     type Target = T;
 
@@ -75,9 +65,9 @@ impl<'a> From<Sp<&'a str>> for Sp<String> {
     }
 }
 
-impl<T: PartialEq> PartialEq for Sp<T> {
-    fn eq(&self, other: &Sp<T>) -> bool {
-        self.val == other.val
+impl<U, T: PartialEq<U>> PartialEq<U> for Sp<T> {
+    fn eq(&self, other: &U) -> bool {
+        self.val == *other
     }
 }
 
diff --git a/examples/01c_quick_example.rs b/examples/01c_quick_example.rs
index 73cacb9d..2197a642 100644
--- a/examples/01c_quick_example.rs
+++ b/examples/01c_quick_example.rs
@@ -1,4 +1,5 @@
-use clap::clap_app;
+#[macro_use]
+extern crate clap;
 
 fn main() {
     // This example shows how to create an application with several arguments using macro builder.
diff --git a/examples/09_auto_version.rs b/examples/09_auto_version.rs
index 923ed61b..ea6d75f9 100644
--- a/examples/09_auto_version.rs
+++ b/examples/09_auto_version.rs
@@ -1,4 +1,7 @@
-use clap::{crate_version, App};
+#[macro_use]
+extern crate clap;
+
+use clap::App;
 
 fn main() {
     // You can have clap pull the application version directly from your Cargo.toml starting with
diff --git a/examples/12_typed_values.rs b/examples/12_typed_values.rs
index 0bfff47e..a59486ec 100644
--- a/examples/12_typed_values.rs
+++ b/examples/12_typed_values.rs
@@ -1,4 +1,7 @@
-use clap::{value_t, values_t, App};
+#[macro_use]
+extern crate clap;
+
+use clap::App;
 
 fn main() {
     // You can use some convenience macros provided by clap to get typed values, so long as the
@@ -19,6 +22,9 @@ fn main() {
     // arguments, because if the argument isn't found, it exits. Just FYI ;)
     //
     // The following example shows both methods.
+    //
+    // **NOTE:** to use the macros, you must include #[macro_use] just above the 'extern crate clap;'
+    // declaration in your crate root.
     let matches = App::new("myapp")
         // Create two arguments, a required positional which accepts multiple values
         // and an optional '-l value'
diff --git a/examples/13a_enum_values_automatic.rs b/examples/13a_enum_values_automatic.rs
index 7dd382b7..3c10db0e 100644
--- a/examples/13a_enum_values_automatic.rs
+++ b/examples/13a_enum_values_automatic.rs
@@ -10,7 +10,10 @@
 // that accepts only one of those values, and use clap to parse the argument.
 
 // Add clap like normal
-use clap::{arg_enum, value_t, App, Arg};
+#[macro_use]
+extern crate clap;
+
+use clap::{App, Arg};
 
 // Using arg_enum! is more like traditional enum declarations
 //
diff --git a/examples/13b_enum_values_manual.rs b/examples/13b_enum_values_manual.rs
index 0e682cd2..3cef8d32 100644
--- a/examples/13b_enum_values_manual.rs
+++ b/examples/13b_enum_values_manual.rs
@@ -5,7 +5,10 @@
 use std::str::FromStr;
 
 // Add clap like normal
-use clap::{value_t, App, Arg};
+#[macro_use]
+extern crate clap;
+
+use clap::{App, Arg};
 
 // Define your enum
 enum Vals {
diff --git a/examples/17_yaml.rs b/examples/17_yaml.rs
index 03419b48..c2d9a0d7 100644
--- a/examples/17_yaml.rs
+++ b/examples/17_yaml.rs
@@ -11,12 +11,17 @@
 // [dependencies]
 // clap = { features = ["yaml"] }
 
-// Using yaml requires calling a clap macro `load_yaml!()`.
+// Using yaml requires calling a clap macro `load_yaml!()` so we must use the '#[macro_use]'
+// directive
 // Note: If you're using clap as a dependency and don't have a feature for your users called
 // "yaml", you'll need to remove the #[cfg(feature = "yaml")] conditional compilation attribute
+#[cfg(feature = "yaml")]
+#[macro_use]
+extern crate clap;
+
 #[cfg(feature = "yaml")]
 fn main() {
-    use clap::{load_yaml, App};
+    use clap::App;
 
     // To load a yaml file containing our CLI definition such as the example '17_yaml.yml' we can
     // use the convenience macro which loads the file at compile relative to the current file
diff --git a/examples/18_builder_macro.rs b/examples/18_builder_macro.rs
index ddc355cc..84b0f9b6 100644
--- a/examples/18_builder_macro.rs
+++ b/examples/18_builder_macro.rs
@@ -1,4 +1,5 @@
-use clap::clap_app;
+#[macro_use]
+extern crate clap;
 
 // Note, there isn't a need for "use clap::{ ... };" Because the clap_app! macro uses
 // $crate:: internally
diff --git a/examples/19_auto_authors.rs b/examples/19_auto_authors.rs
index 98bdd1ea..cfb540e8 100644
--- a/examples/19_auto_authors.rs
+++ b/examples/19_auto_authors.rs
@@ -1,4 +1,7 @@
-use clap::{crate_authors, App};
+#[macro_use]
+extern crate clap;
+
+use clap::App;
 
 fn main() {
     App::new("myapp")
diff --git a/justfile b/justfile
index e6e9e440..2fa2a859 100644
--- a/justfile
+++ b/justfile
@@ -13,13 +13,13 @@
 	rm CONTRIBUTORS.md.bak
 
 run-test TESTG TEST="":
-	cargo test --test {{TESTG}} -- {{TEST}}
+	cargo test --all --test {{TESTG}} -- {{TEST}}
 
 debug TESTG TEST="":
-	cargo test --test {{TESTG}} --features debug -- {{TEST}}
+	cargo test --all --test {{TESTG}} --features debug -- {{TEST}}
 
 run-tests:
-	cargo test --features "yaml unstable"
+	cargo test --all --features "yaml unstable"
 
 @bench:
 	cargo bench
@@ -27,8 +27,8 @@ run-tests:
 @lint:
 	rustup add component clippy
 	rustup add component rustfmt
-	cargo clippy --lib --features "yaml unstable" -- -D warnings
-	cargo clippy --tests --examples --features "yaml unstable"
+	cargo clippy --all --lib --features "yaml unstable" -- -D warnings
+	cargo clippy --all --tests --examples --features "yaml unstable"
 	cargo fmt -- --check
 
 clean:
diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs
index 10a488ed..6e82f8e7 100644
--- a/src/build/app/mod.rs
+++ b/src/build/app/mod.rs
@@ -251,7 +251,9 @@ impl<'b> App<'b> {
     ///
     /// # Examples
     /// ```ignore
-    /// # use clap::{App, load_yaml};
+    /// # #[macro_use]
+    /// # extern crate clap;
+    /// # use clap::App;
     /// let yml = load_yaml!("app.yml");
     /// let app = App::from_yaml(yml)
     ///     .name(crate_name!());
@@ -1195,7 +1197,7 @@ impl<'b> App<'b> {
                         i.lock().read_line(&mut s).unwrap();
                     }
                     drop(e);
-                    process::exit(2);
+                    process::exit(exitcode::USAGE);
                 }
 
                 e.exit()
@@ -1270,7 +1272,7 @@ impl<'b> App<'b> {
                 }
                 drop(self);
                 drop(e);
-                process::exit(2);
+                process::exit(exitcode::USAGE);
             }
 
             drop(self);
diff --git a/src/build/arg/mod.rs b/src/build/arg/mod.rs
index c43e25c7..41f8ec79 100644
--- a/src/build/arg/mod.rs
+++ b/src/build/arg/mod.rs
@@ -162,7 +162,9 @@ impl<'help> Arg<'help> {
     /// # Examples
     ///
     /// ```ignore
-    /// use clap::{Arg, load_yaml};
+    /// # #[macro_use]
+    /// # extern crate clap;
+    /// # use clap::Arg;
     /// let yml = load_yaml!("arg.yml");
     /// let arg = Arg::from_yaml(yml);
     /// ```
diff --git a/src/build/arg_group.rs b/src/build/arg_group.rs
index 9e223c9e..11869be3 100644
--- a/src/build/arg_group.rs
+++ b/src/build/arg_group.rs
@@ -133,7 +133,9 @@ impl<'a> ArgGroup<'a> {
     /// # Examples
     ///
     /// ```ignore
-    /// # use clap::{ArgGroup, load_yaml};
+    /// # #[macro_use]
+    /// # extern crate clap;
+    /// # use clap::ArgGroup;
     /// let yml = load_yaml!("group.yml");
     /// let ag = ArgGroup::from_yaml(yml);
     /// ```
diff --git a/src/lib.rs b/src/lib.rs
index b23080e1..300c292e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -457,7 +457,11 @@ pub use yaml_rust::YamlLoader;
 
 #[cfg(feature = "derive")]
 #[cfg_attr(feature = "derive", doc(hidden))]
-pub use clap_derive::*;
+pub use clap_derive::{self, *};
+
+#[cfg(feature = "derive")]
+#[cfg_attr(feature = "derive", doc(hidden))]
+pub use lazy_static;
 
 use std::result::Result as StdResult;
 
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index df786802..1f4ee098 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -735,12 +735,6 @@ where
                 .filter(|s| starts(s, &*arg_os))
                 .collect::<Vec<_>>();
 
-            for sc in &v {
-                if OsStr::new(sc) == arg_os {
-                    return (true, Some(sc));
-                }
-            }
-
             if v.len() == 1 {
                 return (true, Some(v[0]));
             }


Test patch:
diff --git a/clap-test.rs b/clap-test.rs
new file mode 100644
index 00000000..757f56f1
--- /dev/null
+++ b/clap-test.rs
@@ -0,0 +1,87 @@
+#[allow(unused_imports, dead_code)]
+mod test {
+    use std::str;
+    use std::io::{Cursor, Write};
+
+    use regex::Regex;
+
+    use clap::{App, Arg, ArgGroup};
+
+    fn compare<S, S2>(l: S, r: S2) -> bool
+        where S: AsRef<str>,
+              S2: AsRef<str>
+    {
+        let re = Regex::new("\x1b[^m]*m").unwrap();
+        // Strip out any mismatching \r character on windows that might sneak in on either side
+        let ls = l.as_ref().trim().replace("\r", "");
+        let rs = r.as_ref().trim().replace("\r", "");
+        let left = re.replace_all(&*ls, "");
+        let right = re.replace_all(&*rs, "");
+        let b = left == right;
+        if !b {
+            println!("");
+            println!("--> left");
+            println!("{}", left);
+            println!("--> right");
+            println!("{}", right);
+            println!("--")
+        }
+        b
+    }
+
+    pub fn compare_output(l: App, args: &str, right: &str, stderr: bool) -> bool {
+        let mut buf = Cursor::new(Vec::with_capacity(50));
+        let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
+        let err = res.unwrap_err();
+        err.write_to(&mut buf).unwrap();
+        let content = buf.into_inner();
+        let left = String::from_utf8(content).unwrap();
+        assert_eq!(stderr, err.use_stderr(),
+            "Should Use STDERR failed. Should be {} but is {}", stderr, err.use_stderr());
+        compare(left, right)
+    }
+
+    pub fn compare_output2(l: App, args: &str, right1: &str, right2: &str, stderr: bool) -> bool {
+        let mut buf = Cursor::new(Vec::with_capacity(50));
+        let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
+        let err = res.unwrap_err();
+        err.write_to(&mut buf).unwrap();
+        let content = buf.into_inner();
+        let left = String::from_utf8(content).unwrap();
+        assert_eq!(stderr, err.use_stderr());
+        compare(&*left, right1) || compare(&*left, right2)
+    }
+
+    // Legacy tests from the pyhton script days
+
+    pub fn complex_app() -> App<'static> {
+        let opt3_vals = ["fast", "slow"];
+        let pos3_vals = ["vi", "emacs"];
+        App::new("clap-test")
+            .version("v1.4.8")
+            .about("tests clap library")
+            .author("Kevin K. <kbknapp@gmail.com>")
+            .arg("-o --option=[opt]... 'tests options'")
+            .arg("[positional] 'tests positionals'")
+            .arg(Arg::from("-f --flag... 'tests flags'")
+                .global(true))
+            .args(&[
+                Arg::from("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("long-option-2"),
+                Arg::from("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
+                Arg::from("[positional2] 'tests positionals with exclusions'"),
+                Arg::from("-O --Option [option3] 'specific vals'").possible_values(&opt3_vals),
+                Arg::from("[positional3]... 'tests specific values'").possible_values(&pos3_vals),
+                Arg::from("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
+                Arg::from("--multvalsmo... [one] [two] 'Tests mutliple values, and mult occs'"),
+                Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
+                Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
+            ])
+            .subcommand(App::new("subcmd")
+                                    .about("tests subcommands")
+                                    .version("0.1")
+                                    .author("Kevin K. <kbknapp@gmail.com>")
+                                    .arg("-o --option [scoption]... 'tests options'")
+                                    .arg("-s --subcmdarg [subcmdarg] 'tests other args'")
+                                    .arg("[scpositional] 'tests positionals'"))
+    }
+}
diff --git a/clap_derive/tests/default_value.rs b/clap_derive/tests/default_value.rs
new file mode 100644
index 00000000..6666ac58
--- /dev/null
+++ b/clap_derive/tests/default_value.rs
@@ -0,0 +1,19 @@
+use clap::Clap;
+
+mod utils;
+
+use utils::*;
+
+#[test]
+fn auto_default_value() {
+    #[derive(Clap, PartialEq, Debug)]
+    struct Opt {
+        #[clap(default_value)]
+        arg: i32,
+    }
+    assert_eq!(Opt { arg: 0 }, Opt::parse_from(&["test"]));
+    assert_eq!(Opt { arg: 1 }, Opt::parse_from(&["test", "1"]));
+
+    let help = get_long_help::<Opt>();
+    assert!(help.contains("[default: 0]"));
+}
diff --git a/clap_derive/tests/doc-comments-help.rs b/clap_derive/tests/doc-comments-help.rs
index 81b7fb04..93e9f0a6 100644
--- a/clap_derive/tests/doc-comments-help.rs
+++ b/clap_derive/tests/doc-comments-help.rs
@@ -69,21 +69,26 @@ fn field_long_doc_comment_both_help_long_help() {
     #[derive(Clap, PartialEq, Debug)]
     #[clap(name = "lorem-ipsum", about = "Dolor sit amet")]
     struct LoremIpsum {
-        /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES.
+        /// Dot is removed from multiline comments.
         ///
-        /// Or something else
+        /// Long help
         #[clap(long)]
         foo: bool,
+
+        /// Dot is removed from one short comment.
+        #[clap(long)]
+        bar: bool,
     }
 
     let short_help = get_help::<LoremIpsum>();
     let long_help = get_long_help::<LoremIpsum>();
 
-    assert!(short_help.contains("CIRCUMSTANCES"));
-    assert!(!short_help.contains("CIRCUMSTANCES."));
-    assert!(!short_help.contains("Or something else"));
-    assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"));
-    assert!(long_help.contains("Or something else"));
+    assert!(short_help.contains("Dot is removed from one short comment"));
+    assert!(!short_help.contains("Dot is removed from one short comment."));
+    assert!(short_help.contains("Dot is removed from multiline comments"));
+    assert!(!short_help.contains("Dot is removed from multiline comments."));
+    assert!(long_help.contains("Long help"));
+    assert!(!short_help.contains("Long help"));
 }
 
 #[test]
@@ -114,3 +119,68 @@ fn top_long_doc_comment_both_help_long_help() {
     assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"));
     assert!(long_help.contains("Or something else"));
 }
+
+#[test]
+fn verbatim_doc_comment() {
+    /// DANCE!
+    ///
+    ///                    ()
+    ///                    |
+    ///               (   ()   )
+    ///     ) ________    //  )
+    ///  ()  |\       \  //
+    /// ( \\__ \ ______\//
+    ///    \__) |       |
+    ///      |  |       |
+    ///       \ |       |
+    ///        \|_______|
+    ///        //    \\
+    ///       ((     ||
+    ///        \\    ||
+    ///      ( ()    ||
+    ///       (      () ) )
+    #[derive(Clap, Debug)]
+    #[clap(verbatim_doc_comment)]
+    struct SeeFigure1 {
+        #[clap(long)]
+        foo: bool,
+    }
+
+    let help = get_long_help::<SeeFigure1>();
+    let sample = r#"
+                   ()
+                   |
+              (   ()   )
+    ) ________    //  )
+ ()  |\       \  //
+( \\__ \ ______\//
+   \__) |       |
+     |  |       |
+      \ |       |
+       \|_______|
+       //    \\
+      ((     ||
+       \\    ||
+     ( ()    ||
+      (      () ) )"#;
+
+    assert!(help.contains(sample))
+}
+
+#[test]
+fn verbatim_doc_comment_field() {
+    #[derive(Clap, Debug)]
+    struct App {
+        /// This help ends in a period.
+        #[clap(long, verbatim_doc_comment)]
+        foo: bool,
+        /// This help does not end in a period.
+        #[clap(long)]
+        bar: bool,
+    }
+
+    let help = get_long_help::<App>();
+
+    assert!(help.contains("This help ends in a period."));
+    assert!(help.contains("This help does not end in a period"));
+}
diff --git a/clap_derive/tests/flatten.rs b/clap_derive/tests/flatten.rs
index c35145df..1ccf257b 100644
--- a/clap_derive/tests/flatten.rs
+++ b/clap_derive/tests/flatten.rs
@@ -97,3 +97,37 @@ fn flatten_in_subcommand() {
         Opt::parse_from(&["test", "add", "-i", "43"])
     );
 }
+
+#[test]
+fn merge_subcommands_with_flatten() {
+    #[derive(Clap, PartialEq, Debug)]
+    enum BaseCli {
+        Command1(Command1),
+    }
+
+    #[derive(Clap, PartialEq, Debug)]
+    struct Command1 {
+        arg1: i32,
+    }
+
+    #[derive(Clap, PartialEq, Debug)]
+    struct Command2 {
+        arg2: i32,
+    }
+
+    #[derive(Clap, PartialEq, Debug)]
+    enum Opt {
+        #[clap(flatten)]
+        BaseCli(BaseCli),
+        Command2(Command2),
+    }
+
+    assert_eq!(
+        Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 42 })),
+        Opt::parse_from(&["test", "command1", "42"])
+    );
+    assert_eq!(
+        Opt::Command2(Command2 { arg2: 43 }),
+        Opt::parse_from(&["test", "command2", "43"])
+    );
+}
diff --git a/clap_derive/tests/issues.rs b/clap_derive/tests/issues.rs
index 4cf546ec..95e71a5f 100644
--- a/clap_derive/tests/issues.rs
+++ b/clap_derive/tests/issues.rs
@@ -1,10 +1,12 @@
-// https://github.com/TeXitoi/structopt/issues/151
-// https://github.com/TeXitoi/structopt/issues/289
+// https://github.com/TeXitoi/structopt/issues/{NUMBER}
+
+mod utils;
+use utils::*;
+
+use clap::{ArgGroup, Clap};
 
 #[test]
 fn issue_151() {
-    use clap::{ArgGroup, Clap};
-
     #[derive(Clap, Debug)]
     #[clap(group = ArgGroup::with_name("verb").required(true).multiple(true))]
     struct Opt {
@@ -24,6 +26,7 @@ fn issue_151() {
     assert!(Cli::try_parse_from(&["test", "--foo"]).is_ok());
     assert!(Cli::try_parse_from(&["test", "--bar"]).is_ok());
     assert!(Cli::try_parse_from(&["test", "--zebra"]).is_err());
+    assert!(Cli::try_parse_from(&["test", "--foo", "--bar"]).is_ok());
 }
 
 #[test]
@@ -48,3 +51,25 @@ fn issue_289() {
     assert!(Args::try_parse_from(&["test", "some-command", "test"]).is_ok());
     assert!(Args::try_parse_from(&["test", "some", "test"]).is_ok());
 }
+
+#[test]
+fn issue_324() {
+    fn my_version() -> &'static str {
+        "MY_VERSION"
+    }
+
+    #[derive(Clap)]
+    #[clap(version = my_version())]
+    struct Opt {
+        #[clap(subcommand)]
+        _cmd: Option<SubCommand>,
+    }
+
+    #[derive(Clap)]
+    enum SubCommand {
+        Start,
+    }
+
+    let help = get_long_help::<Opt>();
+    assert!(help.contains("MY_VERSION"));
+}
diff --git a/clap_derive/tests/rename_all_env.rs b/clap_derive/tests/rename_all_env.rs
new file mode 100644
index 00000000..2c8684ea
--- /dev/null
+++ b/clap_derive/tests/rename_all_env.rs
@@ -0,0 +1,46 @@
+mod utils;
+
+use clap::Clap;
+use utils::*;
+
+#[test]
+fn it_works() {
+    #[derive(Debug, PartialEq, Clap)]
+    #[clap(rename_all_env = "kebab")]
+    struct BehaviorModel {
+        #[clap(env)]
+        be_nice: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: be-nice=]"));
+}
+
+#[test]
+fn default_is_screaming() {
+    #[derive(Debug, PartialEq, Clap)]
+    struct BehaviorModel {
+        #[clap(env)]
+        be_nice: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: BE_NICE=]"));
+}
+
+#[test]
+fn overridable() {
+    #[derive(Debug, PartialEq, Clap)]
+    #[clap(rename_all_env = "kebab")]
+    struct BehaviorModel {
+        #[clap(env)]
+        be_nice: String,
+
+        #[clap(rename_all_env = "pascal", env)]
+        be_agressive: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: be-nice=]"));
+    assert!(help.contains("[env: BeAgressive=]"));
+}
diff --git a/clap_derive/tests/ui/clap_derive_name_value_attr.rs b/clap_derive/tests/ui/clap_derive_name_value_attr.rs
deleted file mode 100644
index b497dbf5..00000000
--- a/clap_derive/tests/ui/clap_derive_name_value_attr.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use clap::Clap;
-
-#[derive(Clap, Debug)]
-#[clap(name = "basic")]
-struct Opt {
-    #[clap = "short"]
-    debug: bool,
-}
-
-fn main() {
-    let opt = Opt::parse();
-    println!("{:?}", opt);
-}
-
diff --git a/clap_derive/tests/ui/clap_derive_name_value_attr.stderr b/clap_derive/tests/ui/clap_derive_name_value_attr.stderr
deleted file mode 100644
index 017c434c..00000000
--- a/clap_derive/tests/ui/clap_derive_name_value_attr.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: expected parentheses
-  --> $DIR/clap_derive_name_value_attr.rs:14:12
-   |
-14 |     #[clap = "short"]
-   |            ^
-
-error[E0277]: the trait bound `Opt: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
-  --> $DIR/clap_derive_name_value_attr.rs:11:10
-   |
-11 | #[derive(Clap, Debug)]
-   |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt`
diff --git a/clap_derive/tests/ui/clap_empty_attr.rs b/clap_derive/tests/ui/clap_empty_attr.rs
new file mode 100644
index 00000000..326f2696
--- /dev/null
+++ b/clap_derive/tests/ui/clap_empty_attr.rs
@@ -0,0 +1,16 @@
+use clap::Clap;
+
+#[derive(Clap, Debug)]
+#[clap]
+struct Opt {}
+
+#[derive(Clap, Debug)]
+struct Opt1 {
+    #[clap = "short"]
+    foo: u32
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/clap_derive/tests/ui/clap_empty_attr.stderr b/clap_derive/tests/ui/clap_empty_attr.stderr
new file mode 100644
index 00000000..27a90859
--- /dev/null
+++ b/clap_derive/tests/ui/clap_empty_attr.stderr
@@ -0,0 +1,23 @@
+error: expected attribute arguments in parentheses: #[clap(...)]
+ --> $DIR/clap_empty_attr.rs:4:1
+  |
+4 | #[clap]
+  | ^^^^^^^
+
+error: expected parentheses: #[clap(...)]
+ --> $DIR/clap_empty_attr.rs:9:12
+  |
+9 |     #[clap = "short"]
+  |            ^
+
+error[E0277]: the trait bound `Opt: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
+ --> $DIR/clap_empty_attr.rs:3:10
+  |
+3 | #[derive(Clap, Debug)]
+  |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt`
+
+error[E0277]: the trait bound `Opt1: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
+ --> $DIR/clap_empty_attr.rs:7:10
+  |
+7 | #[derive(Clap, Debug)]
+  |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt1`
diff --git a/clap_derive/tests/ui/clap_derive_empty_attr.rs b/clap_derive/tests/ui/enum_flatten.rs
similarity index 85%
rename from clap_derive/tests/ui/clap_derive_empty_attr.rs
rename to clap_derive/tests/ui/enum_flatten.rs
index 8acad7b2..0c5f3742 100644
--- a/clap_derive/tests/ui/clap_derive_empty_attr.rs
+++ b/clap_derive/tests/ui/enum_flatten.rs
@@ -10,13 +10,12 @@ use clap::Clap;
 
 #[derive(Clap, Debug)]
 #[clap(name = "basic")]
-struct Opt {
-    #[clap]
-    debug: bool,
+enum Opt {
+    #[clap(flatten)]
+    Variant1,
 }
 
 fn main() {
-    let opt = Opt::parse();
+    let opt = Opt::from_args();
     println!("{:?}", opt);
 }
-
diff --git a/clap_derive/tests/ui/clap_derive_empty_attr.stderr b/clap_derive/tests/ui/enum_flatten.stderr
similarity index 63%
rename from clap_derive/tests/ui/clap_derive_empty_attr.stderr
rename to clap_derive/tests/ui/enum_flatten.stderr
index b2dea36a..30e6cac8 100644
--- a/clap_derive/tests/ui/clap_derive_empty_attr.stderr
+++ b/clap_derive/tests/ui/enum_flatten.stderr
@@ -1,11 +1,11 @@
-error: expected parentheses after `clap`
-  --> $DIR/clap_derive_empty_attr.rs:14:7
+error: `flatten` is usable only with single-typed tuple variants
+  --> $DIR/enum_flatten.rs:14:5
    |
-14 |     #[clap]
-   |       ^^^^
+14 |     #[clap(flatten)]
+   |     ^
 
 error[E0277]: the trait bound `Opt: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
-  --> $DIR/clap_derive_empty_attr.rs:11:10
+  --> $DIR/enum_flatten.rs:11:10
    |
 11 | #[derive(Clap, Debug)]
    |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt`
diff --git a/clap_derive/tests/ui/raw.rs b/clap_derive/tests/ui/raw.rs
index b49fd6e8..a5b72ee0 100644
--- a/clap_derive/tests/ui/raw.rs
+++ b/clap_derive/tests/ui/raw.rs
@@ -14,6 +14,11 @@ struct Opt {
     s: String,
 }
 
+#[derive(Clap, Debug)]
+struct Opt2 {
+    #[clap(raw(requires_if = r#""one", "two""#))]
+    s: String,
+}
 fn main() {
     let opt = Opt::parse();
     println!("{:?}", opt);
diff --git a/clap_derive/tests/ui/raw.stderr b/clap_derive/tests/ui/raw.stderr
index 36102cf0..c21c0083 100644
--- a/clap_derive/tests/ui/raw.stderr
+++ b/clap_derive/tests/ui/raw.stderr
@@ -1,15 +1,31 @@
 error: `#[clap(raw(...))` attributes are removed, they are replaced with raw methods
 
   = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)`
-  = note: if you need to call `clap::Arg/App::case_insensitive` method you can do it like this: #[clap(case_insensitive(true))]
+  = note: if you need to call `clap::Arg/App::case_insensitive` method you can do it like this: #[clap(case_insensitive = true)]
 
   --> $DIR/raw.rs:13:12
    |
 13 |     #[clap(raw(case_insensitive = "true"))]
    |            ^^^
 
+error: `#[clap(raw(...))` attributes are removed, they are replaced with raw methods
+
+  = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)`
+  = note: if you need to call `clap::Arg/App::requires_if` method you can do it like this: #[clap(requires_if("one", "two"))]
+
+  --> $DIR/raw.rs:19:12
+   |
+19 |     #[clap(raw(requires_if = r#""one", "two""#))]
+   |            ^^^
+
 error[E0277]: the trait bound `Opt: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
   --> $DIR/raw.rs:11:10
    |
 11 | #[derive(Clap, Debug)]
    |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt`
+
+error[E0277]: the trait bound `Opt2: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
+  --> $DIR/raw.rs:17:10
+   |
+17 | #[derive(Clap, Debug)]
+   |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt2`
diff --git a/clap_derive/tests/ui/struct_flatten.rs b/clap_derive/tests/ui/struct_flatten.rs
deleted file mode 100644
index 36d6bb21..00000000
--- a/clap_derive/tests/ui/struct_flatten.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use clap::Clap;
-
-#[derive(Clap, Debug)]
-#[clap(name = "basic", flatten)]
-struct Opt {
-    #[clap(short)]
-    s: String,
-}
-
-fn main() {
-    let opt = Opt::parse();
-    println!("{:?}", opt);
-}
diff --git a/clap_derive/tests/ui/struct_flatten.stderr b/clap_derive/tests/ui/struct_flatten.stderr
deleted file mode 100644
index bdcfd873..00000000
--- a/clap_derive/tests/ui/struct_flatten.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: flatten is only allowed on fields
-  --> $DIR/struct_flatten.rs:12:24
-   |
-12 | #[clap(name = "basic", flatten)]
-   |                        ^^^^^^^
-
-error[E0277]: the trait bound `Opt: std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not satisfied
-  --> $DIR/struct_flatten.rs:11:10
-   |
-11 | #[derive(Clap, Debug)]
-   |          ^^^^ the trait `std::convert::From<clap::parse::matches::arg_matches::ArgMatches>` is not implemented for `Opt`
diff --git a/clap_test/Cargo.toml b/clap_test/Cargo.toml
new file mode 100644
index 00000000..76b08334
--- /dev/null
+++ b/clap_test/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "clap_test"
+version = "0.1.0"
+authors = ["Kevin K. <kbknapp@gmail.com>"]
+
+[dependencies]
+clap = {path = "../"}
+regex = "0.2"
\ No newline at end of file
diff --git a/clap_test/src/lib.rs b/clap_test/src/lib.rs
new file mode 100644
index 00000000..7da913e6
--- /dev/null
+++ b/clap_test/src/lib.rs
@@ -0,0 +1,60 @@
+use std::str;
+use std::io::Cursor;
+
+extern crate clap;
+extern crate regex;
+
+use regex::Regex;
+
+use clap::App;
+
+fn compare<S, S2>(l: S, r: S2) -> bool
+where
+    S: AsRef<str>,
+    S2: AsRef<str>,
+{
+    let re = Regex::new("\x1b[^m]*m").unwrap();
+    // Strip out any mismatching \r character on windows that might sneak in on either side
+    let ls = l.as_ref().trim().replace("\r", "");
+    let rs = r.as_ref().trim().replace("\r", "");
+    let left = re.replace_all(&*ls, "");
+    let right = re.replace_all(&*rs, "");
+    let b = left == right;
+    if !b {
+        println!("");
+        println!("--> left");
+        println!("{}", left);
+        println!("--> right");
+        println!("{}", right);
+        println!("--")
+    }
+    b
+}
+
+pub fn compare_output(l: App, args: &str, right: &str, stderr: bool) -> bool {
+    let mut buf = Cursor::new(Vec::with_capacity(50));
+    let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
+    let err = res.unwrap_err();
+    err.write_to(&mut buf).unwrap();
+    let content = buf.into_inner();
+    let left = String::from_utf8(content).unwrap();
+    assert_eq!(
+        stderr,
+        err.use_stderr(),
+        "Should Use STDERR failed. Should be {} but is {}",
+        stderr,
+        err.use_stderr()
+    );
+    compare(left, right)
+}
+
+pub fn compare_output2(l: App, args: &str, right1: &str, right2: &str, stderr: bool) -> bool {
+    let mut buf = Cursor::new(Vec::with_capacity(50));
+    let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
+    let err = res.unwrap_err();
+    err.write_to(&mut buf).unwrap();
+    let content = buf.into_inner();
+    let left = String::from_utf8(content).unwrap();
+    assert_eq!(stderr, err.use_stderr());
+    compare(&*left, right1) || compare(&*left, right2)
+}
diff --git a/tests/fixtures/app.yml b/tests/app.yml
similarity index 100%
rename from tests/fixtures/app.yml
rename to tests/app.yml
diff --git a/tests/fixtures/app_2space.yml b/tests/app_2space.yml
similarity index 100%
rename from tests/fixtures/app_2space.yml
rename to tests/app_2space.yml
diff --git a/tests/app_settings.rs b/tests/app_settings.rs
index 266c064e..44cd7e21 100644
--- a/tests/app_settings.rs
+++ b/tests/app_settings.rs
@@ -1,7 +1,10 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
 use clap::{App, AppSettings, Arg, ErrorKind, Propagation};
 
+include!("../clap-test.rs");
+
 static ALLOW_EXT_SC: &str = "clap-test v1.4.8
 
 USAGE:
@@ -201,17 +204,6 @@ fn infer_subcommands_pass_close() {
     assert_eq!(m.subcommand_name(), Some("test"));
 }
 
-#[test]
-fn infer_subcommands_pass_exact_match() {
-    let m = App::new("prog")
-        .setting(AppSettings::InferSubcommands)
-        .subcommand(App::new("test"))
-        .subcommand(App::new("testa"))
-        .subcommand(App::new("testb"))
-        .get_matches_from(vec!["prog", "test"]);
-    assert_eq!(m.subcommand_name(), Some("test"));
-}
-
 #[cfg(feature = "suggestions")]
 #[test]
 fn infer_subcommands_fail_suggestions() {
@@ -259,7 +251,7 @@ fn unified_help() {
         .arg("[arg1] 'some pos arg'")
         .arg("--option [opt] 'some option'");
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         UNIFIED_HELP,
@@ -279,7 +271,7 @@ fn skip_possible_values() {
             Arg::from("[arg1] 'some pos arg'").possible_values(&["three", "four"]),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         SKIP_POS_VALS,
@@ -545,7 +537,7 @@ fn dont_collapse_args() {
             Arg::with_name("arg2").help("some"),
             Arg::with_name("arg3").help("some"),
         ]);
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         DONT_COLLAPSE_ARGS,
@@ -564,7 +556,7 @@ fn require_eq() {
             .value_name("FILE")
             .help("some"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         REQUIRE_EQUALS,
@@ -766,7 +758,7 @@ fn issue_1093_allow_ext_sc() {
     let app = App::new("clap-test")
         .version("v1.4.8")
         .setting(AppSettings::AllowExternalSubcommands);
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         ALLOW_EXT_SC,
diff --git a/tests/arg_aliases.rs b/tests/arg_aliases.rs
index 0331a3d6..9c926c06 100644
--- a/tests/arg_aliases.rs
+++ b/tests/arg_aliases.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg};
 
@@ -173,7 +176,7 @@ fn invisible_arg_aliases_help_output() {
             )
             .arg(Arg::from("-f, --flag").aliases(&["invisible", "flg1", "anyway"])),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ct test --help",
         SC_INVISIBLE_ALIAS_HELP,
@@ -202,7 +205,7 @@ fn visible_arg_aliases_help_output() {
                     .visible_aliases(&["v_flg", "flag2", "flg3"]),
             ),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ct test --help",
         SC_VISIBLE_ALIAS_HELP,
diff --git a/tests/borrowed.rs b/tests/borrowed.rs
index 4b79d921..8a5ff5bb 100644
--- a/tests/borrowed.rs
+++ b/tests/borrowed.rs
@@ -1,5 +1,10 @@
+extern crate clap;
+extern crate regex;
+
 use clap::{App, Arg};
 
+include!("../clap-test.rs");
+
 #[test]
 fn borrowed_args() {
     let arg = Arg::with_name("some")
diff --git a/tests/conflicts.rs b/tests/conflicts.rs
index ca164c9c..d7fe35a2 100644
--- a/tests/conflicts.rs
+++ b/tests/conflicts.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ArgGroup, ErrorKind};
 
@@ -98,8 +101,8 @@ fn group_conflict_2() {
 
 #[test]
 fn conflict_output() {
-    utils::compare_output(
-        utils::complex_app(),
+    test::compare_output(
+        test::complex_app(),
         "clap-test val1 --flag --long-option-2 val2 -F",
         CONFLICT_ERR,
         true,
@@ -108,8 +111,8 @@ fn conflict_output() {
 
 #[test]
 fn conflict_output_rev() {
-    utils::compare_output(
-        utils::complex_app(),
+    test::compare_output(
+        test::complex_app(),
         "clap-test val1 -F --long-option-2 val2 --flag",
         CONFLICT_ERR_REV,
         true,
diff --git a/tests/default_vals.rs b/tests/default_vals.rs
index 9b671d81..3f1ce07d 100644
--- a/tests/default_vals.rs
+++ b/tests/default_vals.rs
@@ -1,3 +1,8 @@
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
+
 use clap::{App, Arg, ErrorKind};
 
 #[test]
diff --git a/tests/delimiters.rs b/tests/delimiters.rs
index 0aecaa96..b5d193cb 100644
--- a/tests/delimiters.rs
+++ b/tests/delimiters.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg, ArgSettings};
 
 #[test]
diff --git a/tests/derive_order.rs b/tests/derive_order.rs
index 9c36afe7..ac56e335 100644
--- a/tests/derive_order.rs
+++ b/tests/derive_order.rs
@@ -1,9 +1,12 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
 use std::str;
 
 use clap::{App, AppSettings, Arg};
 
+include!("../clap-test.rs");
+
 static NO_DERIVE_ORDER: &str = "test 1.2
 
 USAGE:
@@ -129,7 +132,7 @@ fn no_derive_order() {
             .help("second option"),
     ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         NO_DERIVE_ORDER,
@@ -155,7 +158,7 @@ fn derive_order() {
                 .help("second option"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         DERIVE_ORDER,
@@ -181,7 +184,7 @@ fn unified_help() {
                 .help("second option"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         UNIFIED_HELP,
@@ -208,7 +211,7 @@ fn unified_help_and_derive_order() {
                 .help("second option"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         UNIFIED_HELP_AND_DERIVE,
@@ -236,7 +239,7 @@ fn derive_order_subcommand_propagate() {
             ]),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test sub --help",
         DERIVE_ORDER_SC_PROP,
@@ -263,7 +266,7 @@ fn unified_help_subcommand_propagate() {
             ]),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test sub --help",
         UNIFIED_SC_PROP,
@@ -291,7 +294,7 @@ fn unified_help_and_derive_order_subcommand_propagate() {
             ]),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test sub --help",
         UNIFIED_DERIVE_SC_PROP,
@@ -322,7 +325,7 @@ fn unified_help_and_derive_order_subcommand_propagate_with_explicit_display_orde
             ]),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test sub --help",
         UNIFIED_DERIVE_SC_PROP_EXPLICIT_ORDER,
diff --git a/tests/env.rs b/tests/env.rs
index 4fa84e0e..263b6ca5 100644
--- a/tests/env.rs
+++ b/tests/env.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use std::env;
 use std::ffi::OsStr;
 
diff --git a/tests/example1_tmpl_full.txt b/tests/example1_tmpl_full.txt
new file mode 100644
index 00000000..6ae57fa5
--- /dev/null
+++ b/tests/example1_tmpl_full.txt
@@ -0,0 +1,15 @@
+{bin} {version}
+{author}
+{about}
+
+USAGE:
+    {usage}
+
+FLAGS:
+{flags}
+OPTIONS:
+{options}
+ARGS:
+{positionals}
+SUBCOMMANDS:
+{subcommands}
diff --git a/tests/example1_tmpl_simple.txt b/tests/example1_tmpl_simple.txt
new file mode 100644
index 00000000..af6c4b07
--- /dev/null
+++ b/tests/example1_tmpl_simple.txt
@@ -0,0 +1,8 @@
+{bin} {version}
+{author}
+{about}
+
+USAGE:
+    {usage}
+
+{all-args}
diff --git a/tests/flags.rs b/tests/flags.rs
index e2ac8c71..06c05f0b 100644
--- a/tests/flags.rs
+++ b/tests/flags.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg, ArgSettings};
 
 #[test]
diff --git a/tests/global_args.rs b/tests/global_args.rs
index 873234e1..769da9cc 100644
--- a/tests/global_args.rs
+++ b/tests/global_args.rs
@@ -1,31 +1,36 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
-use clap::{App, Arg};
+#[cfg(test)]
+mod tests {
+    include!("../clap-test.rs");
+    use clap::{App, Arg};
 
-fn get_app() -> App<'static> {
-    App::new("myprog")
-        .arg(
-            Arg::with_name("GLOBAL_ARG")
-                .long("global-arg")
-                .help("Specifies something needed by the subcommands")
-                .global(true)
-                .takes_value(true)
-                .default_value("default_value"),
-        )
-        .arg(
-            Arg::with_name("GLOBAL_FLAG")
-                .long("global-flag")
-                .help("Specifies something needed by the subcommands")
-                .multiple(true)
-                .global(true),
-        )
-        .subcommand(App::new("outer").subcommand(App::new("inner")))
-}
+    fn get_app() -> App<'static> {
+        App::new("myprog")
+            .arg(
+                Arg::with_name("GLOBAL_ARG")
+                    .long("global-arg")
+                    .help("Specifies something needed by the subcommands")
+                    .global(true)
+                    .takes_value(true)
+                    .default_value("default_value"),
+            )
+            .arg(
+                Arg::with_name("GLOBAL_FLAG")
+                    .long("global-flag")
+                    .help("Specifies something needed by the subcommands")
+                    .multiple(true)
+                    .global(true),
+            )
+            .subcommand(App::new("outer").subcommand(App::new("inner")))
+    }
 
-#[test]
-fn issue_1076() {
-    let mut app = get_app();
-    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
-    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
-    let _ = app.try_get_matches_from_mut(vec!["myprog"]);
+    #[test]
+    fn issue_1076() {
+        let mut app = get_app();
+        let _ = app.try_get_matches_from_mut(vec!["myprog"]);
+        let _ = app.try_get_matches_from_mut(vec!["myprog"]);
+        let _ = app.try_get_matches_from_mut(vec!["myprog"]);
+    }
 }
diff --git a/tests/groups.rs b/tests/groups.rs
index b7ea3f43..b00576ad 100644
--- a/tests/groups.rs
+++ b/tests/groups.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ArgGroup, ErrorKind};
 
@@ -157,7 +160,7 @@ fn req_group_usage_string() {
                 .required(true),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test",
         REQ_GROUP_USAGE,
@@ -178,7 +181,7 @@ fn req_group_with_conflict_usage_string() {
                 .required(true),
         );
 
-    assert!(utils::compare_output2(
+    assert!(test::compare_output2(
         app,
         "clap-test --delete base",
         REQ_GROUP_CONFLICT_REV,
diff --git a/tests/help.rs b/tests/help.rs
index d7f9f92d..00699426 100644
--- a/tests/help.rs
+++ b/tests/help.rs
@@ -1,6 +1,10 @@
-mod utils;
+#[macro_use]
+extern crate clap;
+extern crate regex;
 
-use clap::{clap_app, App, AppSettings, Arg, ArgGroup, ArgSettings, ErrorKind};
+include!("../clap-test.rs");
+
+use clap::{App, AppSettings, Arg, ArgGroup, ArgSettings, ErrorKind};
 
 static REQUIRE_DELIM_HELP: &str = "test 1.3
 Kevin K.
@@ -593,7 +597,7 @@ fn req_last_arg_usage() {
         (@arg FIRST: ... * "First")
         (@arg SECOND: ... * +last "Second")
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "example --help",
         LAST_ARG_REQ_MULT,
@@ -642,7 +646,7 @@ fn args_with_last_usage() {
                 ])
                 .value_name("ARGS"),
         );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "flamegraph --help",
         LAST_ARG_USAGE,
@@ -652,7 +656,7 @@ fn args_with_last_usage() {
 
 #[test]
 fn subcommand_short_help() {
-    let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "-h"]);
+    let m = test::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "-h"]);
 
     assert!(m.is_err());
     assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
@@ -660,7 +664,7 @@ fn subcommand_short_help() {
 
 #[test]
 fn subcommand_long_help() {
-    let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "--help"]);
+    let m = test::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "--help"]);
 
     assert!(m.is_err());
     assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
@@ -668,7 +672,7 @@ fn subcommand_long_help() {
 
 #[test]
 fn subcommand_help_rev() {
-    let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "help", "subcmd"]);
+    let m = test::complex_app().try_get_matches_from(vec!["clap-test", "help", "subcmd"]);
 
     assert!(m.is_err());
     assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
@@ -676,8 +680,8 @@ fn subcommand_help_rev() {
 
 #[test]
 fn complex_help_output() {
-    assert!(utils::compare_output(
-        utils::complex_app(),
+    assert!(test::compare_output(
+        test::complex_app(),
         "clap-test --help",
         HELP,
         false
@@ -691,7 +695,7 @@ fn after_and_before_help_output() {
         .about("tests clap library")
         .before_help("some text that comes before the help")
         .after_help("some text that comes after the help");
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         AFTER_HELP,
@@ -711,7 +715,7 @@ fn multi_level_sc_help() {
                 .arg("-o, --option [scoption]...    'tests options'"),
         ),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest help subcmd multi",
         MULTI_SC_HELP,
@@ -724,7 +728,7 @@ fn no_wrap_help() {
     let app = App::new("ctest")
         .set_term_width(0)
         .override_help(MULTI_SC_HELP);
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         MULTI_SC_HELP,
@@ -735,7 +739,7 @@ fn no_wrap_help() {
 #[test]
 fn no_wrap_default_help() {
     let app = App::new("ctest").version("1.0").set_term_width(0);
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         DEFAULT_HELP,
@@ -745,8 +749,8 @@ fn no_wrap_default_help() {
 
 #[test]
 fn complex_subcommand_help_output() {
-    let a = utils::complex_app();
-    assert!(utils::compare_output(
+    let a = test::complex_app();
+    assert!(test::compare_output(
         a,
         "clap-test subcmd --help",
         SC_HELP,
@@ -771,7 +775,7 @@ fn issue_626_unicode_cutoff() {
             )
             .takes_value(true),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         ISSUE_626_CUTOFF,
@@ -802,7 +806,7 @@ fn hide_possible_vals() {
                 .help("A coffeehouse, coffee shop, or café.")
                 .takes_value(true),
         );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         HIDE_POS_VALS,
@@ -823,7 +827,7 @@ fn issue_626_panic() {
            d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
            Le café est souvent une contribution majeure aux exportations des régions productrices.")
            .takes_value(true));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         ISSUE_626_PANIC,
@@ -852,7 +856,7 @@ fn issue_626_variable_panic() {
 #[test]
 fn final_word_wrapping() {
     let app = App::new("ctest").version("0.1").set_term_width(24);
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         FINAL_WORD_WRAPPING,
@@ -870,7 +874,7 @@ fn wrapping_newline_chars() {
              l, long           Copy-friendly, 14 characters, contains symbols.{n}\
              m, med, medium    Copy-friendly, 8 characters, contains symbols.{n}",
         ));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         WRAPPING_NEWLINE_CHARS,
@@ -885,7 +889,7 @@ fn old_newline_chars() {
             .short('m')
             .help("Some help with some wrapping{n}(Defaults to something)"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         OLD_NEWLINE_CHARS,
@@ -907,12 +911,7 @@ fn issue_688_hidden_pos_vals() {
 				.long("filter")
 				.possible_values(&filter_values)
 				.takes_value(true));
-    assert!(utils::compare_output(
-        app1,
-        "ctest --help",
-        ISSUE_688,
-        false
-    ));
+    assert!(test::compare_output(app1, "ctest --help", ISSUE_688, false));
 
     let app2 = App::new("ctest")
             .version("0.1")
@@ -923,12 +922,7 @@ fn issue_688_hidden_pos_vals() {
 				.long("filter")
 				.possible_values(&filter_values)
 				.takes_value(true));
-    assert!(utils::compare_output(
-        app2,
-        "ctest --help",
-        ISSUE_688,
-        false
-    ));
+    assert!(test::compare_output(app2, "ctest --help", ISSUE_688, false));
 
     let app3 = App::new("ctest")
             .version("0.1")
@@ -938,12 +932,7 @@ fn issue_688_hidden_pos_vals() {
                 images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
 				.long("filter")
 				.takes_value(true));
-    assert!(utils::compare_output(
-        app3,
-        "ctest --help",
-        ISSUE_688,
-        false
-    ));
+    assert!(test::compare_output(app3, "ctest --help", ISSUE_688, false));
 }
 
 #[test]
@@ -976,7 +965,7 @@ fn issue_702_multiple_values() {
                 .multiple(true)
                 .takes_value(true),
         );
-    assert!(utils::compare_output(app, "myapp --help", ISSUE_702, false));
+    assert!(test::compare_output(app, "myapp --help", ISSUE_702, false));
 }
 
 #[test]
@@ -989,12 +978,7 @@ fn long_about() {
             "something really really long, with\nmultiple lines of text\nthat should be displayed",
         )
         .arg(Arg::with_name("arg1").help("some option"));
-    assert!(utils::compare_output(
-        app,
-        "myapp --help",
-        LONG_ABOUT,
-        false
-    ));
+    assert!(test::compare_output(app, "myapp --help", LONG_ABOUT, false));
 }
 
 #[test]
@@ -1017,7 +1001,7 @@ fn issue_760() {
                 .long("opt")
                 .takes_value(true),
         );
-    assert!(utils::compare_output(app, "ctest --help", ISSUE_760, false));
+    assert!(test::compare_output(app, "ctest --help", ISSUE_760, false));
 }
 
 #[test]
@@ -1029,12 +1013,7 @@ fn ripgrep_usage() {
     rg [OPTIONS] --type-list",
     );
 
-    assert!(utils::compare_output(
-        app,
-        "rg --help",
-        RIPGREP_USAGE,
-        false
-    ));
+    assert!(test::compare_output(app, "rg --help", RIPGREP_USAGE, false));
 }
 
 #[test]
@@ -1058,12 +1037,7 @@ FLAGS:
 {flags}",
         );
 
-    assert!(utils::compare_output(
-        app,
-        "rg --help",
-        RIPGREP_USAGE,
-        false
-    ));
+    assert!(test::compare_output(app, "rg --help", RIPGREP_USAGE, false));
 }
 
 #[test]
@@ -1074,7 +1048,7 @@ fn sc_negates_reqs() {
         .arg("-o, --opt <FILE> 'tests options'")
         .arg(Arg::with_name("PATH").help("help"))
         .subcommand(App::new("test"));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "prog --help",
         SC_NEGATES_REQS,
@@ -1089,12 +1063,7 @@ fn hidden_args() {
         .arg("-f, --flag 'testing flags'")
         .arg("-o, --opt [FILE] 'tests options'")
         .arg(Arg::with_name("pos").hidden(true));
-    assert!(utils::compare_output(
-        app,
-        "prog --help",
-        HIDDEN_ARGS,
-        false
-    ));
+    assert!(test::compare_output(app, "prog --help", HIDDEN_ARGS, false));
 }
 
 #[test]
@@ -1106,7 +1075,7 @@ fn args_negate_sc() {
         .arg("-o, --opt [FILE] 'tests options'")
         .arg(Arg::with_name("PATH").help("help"))
         .subcommand(App::new("test"));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "prog --help",
         ARGS_NEGATE_SC,
@@ -1122,7 +1091,7 @@ fn issue_1046_hidden_scs() {
         .arg("-o, --opt [FILE] 'tests options'")
         .arg(Arg::with_name("PATH").help("some"))
         .subcommand(App::new("test").setting(AppSettings::Hidden));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "prog --help",
         ISSUE_1046_HIDDEN_SCS,
@@ -1137,7 +1106,7 @@ fn issue_777_wrap_all_things() {
         .author("Some Very Long Name and crazy long email <email@server.com>")
         .about("Show how the about text is not wrapped")
         .set_term_width(35);
-    assert!(utils::compare_output(app, "ctest --help", ISSUE_777, false));
+    assert!(test::compare_output(app, "ctest --help", ISSUE_777, false));
 }
 
 #[test]
@@ -1154,7 +1123,7 @@ fn customize_version_and_help() {
                 .long("version")
                 .help("Print version information")
         });
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "customize --help",
         CUSTOM_VERSION_AND_HELP,
@@ -1174,7 +1143,7 @@ fn last_arg_mult_usage() {
                 .last(true)
                 .help("some"),
         );
-    assert!(utils::compare_output(app, "last --help", LAST_ARG, false));
+    assert!(test::compare_output(app, "last --help", LAST_ARG, false));
 }
 
 #[test]
@@ -1190,7 +1159,7 @@ fn last_arg_mult_usage_req() {
                 .required(true)
                 .help("some"),
         );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "last --help",
         LAST_ARG_REQ,
@@ -1213,7 +1182,7 @@ fn last_arg_mult_usage_req_with_sc() {
                 .help("some"),
         )
         .subcommand(App::new("test").about("some"));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "last --help",
         LAST_ARG_REQ_SC,
@@ -1235,12 +1204,7 @@ fn last_arg_mult_usage_with_sc() {
                 .help("some"),
         )
         .subcommand(App::new("test").about("some"));
-    assert!(utils::compare_output(
-        app,
-        "last --help",
-        LAST_ARG_SC,
-        false
-    ));
+    assert!(test::compare_output(app, "last --help", LAST_ARG_SC, false));
 }
 
 #[test]
@@ -1252,7 +1216,7 @@ fn hidden_default_val() {
             .default_value("default-argument")
             .hide_default_value(true),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app1,
         "default --help",
         HIDE_DEFAULT_VAL,
@@ -1265,7 +1229,7 @@ fn hidden_default_val() {
             .long("arg")
             .default_value("default-argument"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app2,
         "default --help",
         HIDE_DEFAULT_VAL,
@@ -1335,7 +1299,7 @@ fn issue_1052_require_delim_help() {
                 .value_delimiter(":"),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         REQUIRE_DELIM_HELP,
@@ -1369,7 +1333,7 @@ fn hide_env_vals() {
                 .help("A coffeehouse, coffee shop, or café.")
                 .takes_value(true),
         );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         HIDE_ENV_VALS,
@@ -1403,7 +1367,7 @@ fn show_env_vals() {
                 .help("A coffeehouse, coffee shop, or café.")
                 .takes_value(true),
         );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest --help",
         SHOW_ENV_VALS,
@@ -1430,7 +1394,7 @@ fn custom_headers_headers() {
                 .help("Do not use system proxy settings"),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         CUSTOM_HELP_SECTION,
@@ -1492,7 +1456,7 @@ fn multiple_custom_help_headers() {
                 .takes_value(true),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         MULTIPLE_CUSTOM_HELP_SECTIONS,
@@ -1521,7 +1485,7 @@ fn show_long_about_issue_897() {
             .about("About foo")
             .long_about("Long about foo"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest foo --help",
         ISSUE_897,
@@ -1547,7 +1511,7 @@ fn show_short_about_issue_897() {
             .about("About foo")
             .long_about("Long about foo"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "ctest foo -h",
         ISSUE_897_SHORT,
@@ -1566,5 +1530,5 @@ fn issue_1487() {
         .group(ArgGroup::with_name("group1")
             .args(&["arg1", "arg2"])
             .required(true));
-    assert!(utils::compare_output(app, "ctest -h", ISSUE_1487, false));
+    assert!(test::compare_output(app, "ctest -h", ISSUE_1487, false));
 }
diff --git a/tests/hidden_args.rs b/tests/hidden_args.rs
index 0ced6b70..a560d560 100644
--- a/tests/hidden_args.rs
+++ b/tests/hidden_args.rs
@@ -1,7 +1,10 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
 use clap::{App, Arg};
 
+include!("../clap-test.rs");
+
 static HIDDEN_ARGS: &str = "test 1.4
 Kevin K.
 tests stuff
@@ -29,12 +32,7 @@ fn hidden_args() {
             Arg::from("--option [opt] 'some option'"),
             Arg::with_name("DUMMY").hidden(true),
         ]);
-    assert!(utils::compare_output(
-        app,
-        "test --help",
-        HIDDEN_ARGS,
-        false
-    ));
+    assert!(test::compare_output(app, "test --help", HIDDEN_ARGS, false));
 }
 
 static HIDDEN_SHORT_ARGS: &str = "test 2.31.2
@@ -88,7 +86,7 @@ fn hidden_short_args() {
                 .help("This text should be visible"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test -h",
         HIDDEN_SHORT_ARGS,
@@ -115,7 +113,7 @@ fn hidden_short_args_long_help() {
                 .help("This text should be visible"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         HIDDEN_SHORT_ARGS_LONG_HELP,
@@ -158,7 +156,7 @@ fn hidden_long_args() {
                 .help("This text should be visible"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --help",
         HIDDEN_LONG_ARGS,
@@ -197,7 +195,7 @@ fn hidden_long_args_short_help() {
                 .help("This text should be visible"),
         ]);
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test -h",
         HIDDEN_LONG_ARGS_SHORT_HELP,
diff --git a/tests/indices.rs b/tests/indices.rs
index 1e68c187..60295295 100644
--- a/tests/indices.rs
+++ b/tests/indices.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg};
 
diff --git a/tests/macros.rs b/tests/macros.rs
index d24e20ef..d4e5f4a1 100644
--- a/tests/macros.rs
+++ b/tests/macros.rs
@@ -1,4 +1,7 @@
-use clap::{arg_enum, clap_app, ErrorKind};
+#[macro_use]
+extern crate clap;
+
+use clap::ErrorKind;
 
 #[test]
 fn basic() {
diff --git a/tests/multiple_occurrences.rs b/tests/multiple_occurrences.rs
index 1a40bd95..caa74280 100644
--- a/tests/multiple_occurrences.rs
+++ b/tests/multiple_occurrences.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg, ArgSettings};
 
 #[test]
diff --git a/tests/multiple_values.rs b/tests/multiple_values.rs
index 616f5ea5..001adafa 100644
--- a/tests/multiple_values.rs
+++ b/tests/multiple_values.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg, ErrorKind};
 
 #[test]
diff --git a/tests/opts.rs b/tests/opts.rs
index ca693262..cfd454f3 100644
--- a/tests/opts.rs
+++ b/tests/opts.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ArgMatches, ArgSettings, ErrorKind};
 
@@ -358,8 +361,8 @@ fn leading_hyphen_with_only_pos_follows() {
 #[test]
 #[cfg(feature = "suggestions")]
 fn did_you_mean() {
-    assert!(utils::compare_output(
-        utils::complex_app(),
+    assert!(test::compare_output(
+        test::complex_app(),
         "clap-test --optio=foo",
         DYM,
         true
diff --git a/tests/positionals.rs b/tests/positionals.rs
index 54c3584a..725147fd 100644
--- a/tests/positionals.rs
+++ b/tests/positionals.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg, ErrorKind};
 
 #[test]
diff --git a/tests/posix_compatible.rs b/tests/posix_compatible.rs
index be3a72ed..ab5cc217 100644
--- a/tests/posix_compatible.rs
+++ b/tests/posix_compatible.rs
@@ -1,5 +1,6 @@
-use clap::{App, Arg, ErrorKind};
+extern crate clap;
 
+use clap::{App, Arg, ErrorKind};
 #[test]
 fn flag_overrides_itself() {
     let res = App::new("posix")
diff --git a/tests/possible_values.rs b/tests/possible_values.rs
index f7b8b971..2c4eb1ca 100644
--- a/tests/possible_values.rs
+++ b/tests/possible_values.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ErrorKind};
 
@@ -171,8 +174,8 @@ fn possible_values_of_option_multiple_fail() {
 
 #[test]
 fn possible_values_output() {
-    assert!(utils::compare_output(
-        utils::complex_app(),
+    assert!(test::compare_output(
+        test::complex_app(),
         "clap-test -O slo",
         PV_ERROR,
         true
diff --git a/tests/propagate_globals.rs b/tests/propagate_globals.rs
index 8a78d914..4843ac12 100644
--- a/tests/propagate_globals.rs
+++ b/tests/propagate_globals.rs
@@ -1,145 +1,150 @@
-mod utils;
-
-use clap::{App, Arg, ArgMatches, ArgSettings};
-
-fn get_app() -> App<'static> {
-    App::new("myprog")
-        .arg(
-            Arg::with_name("GLOBAL_ARG")
-                .long("global-arg")
-                .help("Specifies something needed by the subcommands")
-                .global(true)
-                .setting(ArgSettings::TakesValue)
-                .default_value("default_value"),
-        )
-        .arg(
-            Arg::with_name("GLOBAL_FLAG")
-                .long("global-flag")
-                .help("Specifies something needed by the subcommands")
-                .global(true)
-                .setting(ArgSettings::MultipleOccurrences),
-        )
-        .subcommand(App::new("outer").subcommand(App::new("inner")))
-}
-
-fn get_matches(app: App<'static>, argv: &'static str) -> ArgMatches {
-    app.get_matches_from(argv.split(' ').collect::<Vec<_>>())
-}
-
-fn get_outer_matches(m: &ArgMatches) -> &ArgMatches {
-    m.subcommand_matches("outer")
-        .expect("could not access outer subcommand")
-}
-
-fn get_inner_matches(m: &ArgMatches) -> &ArgMatches {
-    get_outer_matches(m)
-        .subcommand_matches("inner")
-        .expect("could not access inner subcommand")
-}
-
-fn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
-    m.value_of("GLOBAL_ARG") == val.into()
-}
-
-fn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
-    get_inner_matches(m).value_of("GLOBAL_ARG") == val.into()
-}
-
-fn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
-    get_outer_matches(m).value_of("GLOBAL_ARG") == val.into()
-}
-
-fn top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
-    (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
-}
-
-fn inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
-    let m = get_inner_matches(m);
-    (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
-}
-
-fn outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
-    let m = get_outer_matches(m);
-    (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
-}
-
-#[test]
-fn global_arg_used_top_level() {
-    let m = get_matches(get_app(), "myprog --global-arg=some_value outer inner");
-
-    assert!(top_can_access_arg(&m, "some_value"));
-    assert!(inner_can_access_arg(&m, "some_value"));
-    assert!(outer_can_access_arg(&m, "some_value"));
-}
-
-#[test]
-fn global_arg_used_outer() {
-    let m = get_matches(get_app(), "myprog outer --global-arg=some_value inner");
-
-    assert!(top_can_access_arg(&m, "some_value"));
-    assert!(inner_can_access_arg(&m, "some_value"));
-    assert!(outer_can_access_arg(&m, "some_value"));
-}
-
-#[test]
-fn global_arg_used_inner() {
-    let m = get_matches(get_app(), "myprog outer inner --global-arg=some_value");
-
-    assert!(top_can_access_arg(&m, "some_value"));
-    assert!(inner_can_access_arg(&m, "some_value"));
-    assert!(outer_can_access_arg(&m, "some_value"));
-}
-
-#[test]
-fn global_arg_default_value() {
-    let m = get_matches(get_app(), "myprog outer inner");
-
-    assert!(top_can_access_arg(&m, "default_value"));
-    assert!(inner_can_access_arg(&m, "default_value"));
-    assert!(outer_can_access_arg(&m, "default_value"));
-}
-
-#[test]
-fn global_flag_used_top_level() {
-    let m = get_matches(get_app(), "myprog --global-flag outer inner");
-
-    assert!(top_can_access_flag(&m, true, 1));
-    assert!(inner_can_access_flag(&m, true, 1));
-    assert!(outer_can_access_flag(&m, true, 1));
-}
-
-#[test]
-fn global_flag_used_outer() {
-    let m = get_matches(get_app(), "myprog outer --global-flag inner");
-
-    assert!(top_can_access_flag(&m, true, 1));
-    assert!(inner_can_access_flag(&m, true, 1));
-    assert!(outer_can_access_flag(&m, true, 1));
-}
-
-#[test]
-fn global_flag_used_inner() {
-    let m = get_matches(get_app(), "myprog outer inner --global-flag");
-
-    assert!(top_can_access_flag(&m, true, 1));
-    assert!(inner_can_access_flag(&m, true, 1));
-    assert!(outer_can_access_flag(&m, true, 1));
-}
-
-#[test]
-fn global_flag_2x_used_top_level() {
-    let m = get_matches(get_app(), "myprog --global-flag --global-flag outer inner");
-
-    assert!(top_can_access_flag(&m, true, 2));
-    assert!(inner_can_access_flag(&m, true, 2));
-    assert!(outer_can_access_flag(&m, true, 2));
-}
-
-#[test]
-fn global_flag_2x_used_inner() {
-    let m = get_matches(get_app(), "myprog outer inner --global-flag --global-flag");
-
-    assert!(top_can_access_flag(&m, true, 2));
-    assert!(inner_can_access_flag(&m, true, 2));
-    assert!(outer_can_access_flag(&m, true, 2));
+extern crate clap;
+extern crate regex;
+
+#[cfg(test)]
+mod tests {
+    include!("../clap-test.rs");
+    use clap::{App, Arg, ArgMatches, ArgSettings};
+
+    fn get_app() -> App<'static> {
+        App::new("myprog")
+            .arg(
+                Arg::with_name("GLOBAL_ARG")
+                    .long("global-arg")
+                    .help("Specifies something needed by the subcommands")
+                    .global(true)
+                    .setting(ArgSettings::TakesValue)
+                    .default_value("default_value"),
+            )
+            .arg(
+                Arg::with_name("GLOBAL_FLAG")
+                    .long("global-flag")
+                    .help("Specifies something needed by the subcommands")
+                    .global(true)
+                    .setting(ArgSettings::MultipleOccurrences),
+            )
+            .subcommand(App::new("outer").subcommand(App::new("inner")))
+    }
+
+    fn get_matches(app: App<'static>, argv: &'static str) -> ArgMatches {
+        app.get_matches_from(argv.split(' ').collect::<Vec<_>>())
+    }
+
+    fn get_outer_matches(m: &ArgMatches) -> &ArgMatches {
+        m.subcommand_matches("outer")
+            .expect("could not access outer subcommand")
+    }
+
+    fn get_inner_matches(m: &ArgMatches) -> &ArgMatches {
+        get_outer_matches(m)
+            .subcommand_matches("inner")
+            .expect("could not access inner subcommand")
+    }
+
+    fn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
+        m.value_of("GLOBAL_ARG") == val.into()
+    }
+
+    fn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
+        get_inner_matches(m).value_of("GLOBAL_ARG") == val.into()
+    }
+
+    fn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
+        get_outer_matches(m).value_of("GLOBAL_ARG") == val.into()
+    }
+
+    fn top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
+        (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
+    }
+
+    fn inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
+        let m = get_inner_matches(m);
+        (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
+    }
+
+    fn outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
+        let m = get_outer_matches(m);
+        (m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
+    }
+
+    #[test]
+    fn global_arg_used_top_level() {
+        let m = get_matches(get_app(), "myprog --global-arg=some_value outer inner");
+
+        assert!(top_can_access_arg(&m, "some_value"));
+        assert!(inner_can_access_arg(&m, "some_value"));
+        assert!(outer_can_access_arg(&m, "some_value"));
+    }
+
+    #[test]
+    fn global_arg_used_outer() {
+        let m = get_matches(get_app(), "myprog outer --global-arg=some_value inner");
+
+        assert!(top_can_access_arg(&m, "some_value"));
+        assert!(inner_can_access_arg(&m, "some_value"));
+        assert!(outer_can_access_arg(&m, "some_value"));
+    }
+
+    #[test]
+    fn global_arg_used_inner() {
+        let m = get_matches(get_app(), "myprog outer inner --global-arg=some_value");
+
+        assert!(top_can_access_arg(&m, "some_value"));
+        assert!(inner_can_access_arg(&m, "some_value"));
+        assert!(outer_can_access_arg(&m, "some_value"));
+    }
+
+    #[test]
+    fn global_arg_default_value() {
+        let m = get_matches(get_app(), "myprog outer inner");
+
+        assert!(top_can_access_arg(&m, "default_value"));
+        assert!(inner_can_access_arg(&m, "default_value"));
+        assert!(outer_can_access_arg(&m, "default_value"));
+    }
+
+    #[test]
+    fn global_flag_used_top_level() {
+        let m = get_matches(get_app(), "myprog --global-flag outer inner");
+
+        assert!(top_can_access_flag(&m, true, 1));
+        assert!(inner_can_access_flag(&m, true, 1));
+        assert!(outer_can_access_flag(&m, true, 1));
+    }
+
+    #[test]
+    fn global_flag_used_outer() {
+        let m = get_matches(get_app(), "myprog outer --global-flag inner");
+
+        assert!(top_can_access_flag(&m, true, 1));
+        assert!(inner_can_access_flag(&m, true, 1));
+        assert!(outer_can_access_flag(&m, true, 1));
+    }
+
+    #[test]
+    fn global_flag_used_inner() {
+        let m = get_matches(get_app(), "myprog outer inner --global-flag");
+
+        assert!(top_can_access_flag(&m, true, 1));
+        assert!(inner_can_access_flag(&m, true, 1));
+        assert!(outer_can_access_flag(&m, true, 1));
+    }
+
+    #[test]
+    fn global_flag_2x_used_top_level() {
+        let m = get_matches(get_app(), "myprog --global-flag --global-flag outer inner");
+
+        assert!(top_can_access_flag(&m, true, 2));
+        assert!(inner_can_access_flag(&m, true, 2));
+        assert!(outer_can_access_flag(&m, true, 2));
+    }
+
+    #[test]
+    fn global_flag_2x_used_inner() {
+        let m = get_matches(get_app(), "myprog outer inner --global-flag --global-flag");
+
+        assert!(top_can_access_flag(&m, true, 2));
+        assert!(inner_can_access_flag(&m, true, 2));
+        assert!(outer_can_access_flag(&m, true, 2));
+    }
 }
diff --git a/tests/require.rs b/tests/require.rs
index 0da7bbf9..9849eda7 100644
--- a/tests/require.rs
+++ b/tests/require.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ArgGroup, ErrorKind};
 
@@ -421,8 +424,8 @@ fn required_unless_one_err() {
 
 #[test]
 fn missing_required_output() {
-    assert!(utils::compare_output(
-        utils::complex_app(),
+    assert!(test::compare_output(
+        test::complex_app(),
         "clap-test -F",
         MISSING_REQ,
         true
@@ -554,7 +557,7 @@ fn required_if_val_present_fail_error_output() {
                 .long("output"),
         );
 
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "test --input somepath --target file",
         COND_REQ_IN_USAGE,
@@ -654,12 +657,7 @@ fn require_eq() {
             .value_name("FILE")
             .help("some"),
     );
-    assert!(utils::compare_output(
-        app,
-        "clap-test",
-        REQUIRE_EQUALS,
-        true
-    ));
+    assert!(test::compare_output(app, "clap-test", REQUIRE_EQUALS, true));
 }
 
 static ISSUE_1158: &str = "error: The following required arguments were not provided:
@@ -694,7 +692,7 @@ fn issue_1158_app() -> App<'static> {
 fn issue_1158_conflicting_requirements() {
     let app = issue_1158_app();
 
-    assert!(utils::compare_output(app, "example id", ISSUE_1158, true));
+    assert!(test::compare_output(app, "example id", ISSUE_1158, true));
 }
 
 #[test]
diff --git a/tests/subcommands.rs b/tests/subcommands.rs
index af72d264..4d6b788d 100644
--- a/tests/subcommands.rs
+++ b/tests/subcommands.rs
@@ -1,4 +1,7 @@
-mod utils;
+extern crate clap;
+extern crate regex;
+
+include!("../clap-test.rs");
 
 use clap::{App, Arg, ErrorKind};
 
@@ -133,7 +136,7 @@ fn multiple_aliases() {
 #[cfg(feature = "suggestions")]
 fn subcmd_did_you_mean_output() {
     let app = App::new("dym").subcommand(App::new("subcmd"));
-    assert!(utils::compare_output(app, "dym subcm", DYM_SUBCMD, true));
+    assert!(test::compare_output(app, "dym subcm", DYM_SUBCMD, true));
 }
 
 #[test]
@@ -141,7 +144,7 @@ fn subcmd_did_you_mean_output() {
 fn subcmd_did_you_mean_output_arg() {
     let app =
         App::new("dym").subcommand(App::new("subcmd").arg("-s --subcmdarg [subcmdarg] 'tests'"));
-    assert!(utils::compare_output(app, "dym --subcm foo", DYM_ARG, true));
+    assert!(test::compare_output(app, "dym --subcm foo", DYM_ARG, true));
 }
 
 #[test]
@@ -162,7 +165,7 @@ fn visible_aliases_help_output() {
             .visible_alias("dongle")
             .visible_alias("done"),
     );
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         VISIBLE_ALIAS_HELP,
@@ -175,7 +178,7 @@ fn invisible_aliases_help_output() {
     let app = App::new("clap-test")
         .version("2.6")
         .subcommand(App::new("test").about("Some help").alias("invisible"));
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "clap-test --help",
         INVISIBLE_ALIAS_HELP,
diff --git a/tests/template_help.rs b/tests/template_help.rs
index 5f1f5d73..a1f2013a 100644
--- a/tests/template_help.rs
+++ b/tests/template_help.rs
@@ -1,31 +1,12 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
 use clap::App;
 
-static EXAMPLE1_TMPL_S: &str = "{bin} {version}
-{author}
-{about}
+include!("../clap-test.rs");
 
-USAGE:
-    {usage}
-
-{all-args}";
-
-static EXAMPLE1_TMPS_F: &str = "{bin} {version}
-{author}
-{about}
-
-USAGE:
-    {usage}
-
-FLAGS:
-{flags}
-OPTIONS:
-{options}
-ARGS:
-{positionals}
-SUBCOMMANDS:
-{subcommands}";
+static EXAMPLE1_TMPL_S: &str = include_str!("example1_tmpl_simple.txt");
+static EXAMPLE1_TMPS_F: &str = include_str!("example1_tmpl_full.txt");
 
 static CUSTOM_TEMPL_HELP: &str = "MyApp 1.0
 Kevin K. <kbknapp@gmail.com>
@@ -70,8 +51,8 @@ SUBCOMMANDS:
 
 #[test]
 fn with_template() {
-    let app = get_app().help_template(EXAMPLE1_TMPL_S);
-    assert!(utils::compare_output(
+    let app = app_example1().help_template(EXAMPLE1_TMPL_S);
+    assert!(test::compare_output(
         app,
         "MyApp --help",
         SIMPLE_TEMPLATE,
@@ -81,8 +62,8 @@ fn with_template() {
 
 #[test]
 fn custom_template() {
-    let app = get_app().help_template(EXAMPLE1_TMPS_F);
-    assert!(utils::compare_output(
+    let app = app_example1().help_template(EXAMPLE1_TMPS_F);
+    assert!(test::compare_output(
         app,
         "MyApp --help",
         CUSTOM_TEMPL_HELP,
@@ -97,7 +78,7 @@ fn template_empty() {
         .author("Kevin K. <kbknapp@gmail.com>")
         .about("Does awesome things")
         .help_template("");
-    assert!(utils::compare_output(app, "MyApp --help", "", false));
+    assert!(test::compare_output(app, "MyApp --help", "", false));
 }
 
 #[test]
@@ -107,7 +88,7 @@ fn template_notag() {
         .author("Kevin K. <kbknapp@gmail.com>")
         .about("Does awesome things")
         .help_template("test no tag test");
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "MyApp --help",
         "test no tag test",
@@ -122,7 +103,7 @@ fn template_unknowntag() {
         .author("Kevin K. <kbknapp@gmail.com>")
         .about("Does awesome things")
         .help_template("test {unknown_tag} test");
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "MyApp --help",
         "test {unknown_tag} test",
@@ -137,7 +118,7 @@ fn template_author_version() {
         .author("Kevin K. <kbknapp@gmail.com>")
         .about("Does awesome things")
         .help_template("{author}\n{version}\n{about}\n{bin}");
-    assert!(utils::compare_output(
+    assert!(test::compare_output(
         app,
         "MyApp --help",
         "Kevin K. <kbknapp@gmail.com>\n1.0\nDoes awesome things\nMyApp",
@@ -147,7 +128,7 @@ fn template_author_version() {
 
 // ----------
 
-fn get_app() -> App<'static> {
+fn app_example1<'c>() -> App<'c> {
     App::new("MyApp")
         .version("1.0")
         .author("Kevin K. <kbknapp@gmail.com>")
diff --git a/tests/tests.rs b/tests/tests.rs
index 5e58a41e..d2ab9aa6 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -1,9 +1,13 @@
-mod utils;
+#[macro_use]
+extern crate clap;
+extern crate regex;
 
 use std::io::Write;
 use std::str;
 
-use clap::{arg_enum, App, Arg};
+include!("../clap-test.rs");
+
+use clap::{App, Arg};
 
 static SCF2OP: &str = "flag present 2 times
 option NOT present
@@ -88,7 +92,7 @@ subcmd NOT present
 
 pub fn check_complex_output(args: &str, out: &str) {
     let mut w = vec![];
-    let matches = utils::complex_app().get_matches_from(args.split(' ').collect::<Vec<_>>());
+    let matches = test::complex_app().get_matches_from(args.split(' ').collect::<Vec<_>>());
     if matches.is_present("flag") {
         writeln!(w, "flag present {} times", matches.occurrences_of("flag")).unwrap();
     } else {
diff --git a/tests/unique_args.rs b/tests/unique_args.rs
index 5b8ae149..6f3d41e8 100644
--- a/tests/unique_args.rs
+++ b/tests/unique_args.rs
@@ -1,3 +1,5 @@
+extern crate clap;
+
 use clap::{App, Arg};
 
 // This tests a programmer error and will only succeed with debug_assertions
diff --git a/tests/utf8.rs b/tests/utf8.rs
index a2aa404f..23064d06 100644
--- a/tests/utf8.rs
+++ b/tests/utf8.rs
@@ -1,5 +1,7 @@
 #![cfg(not(windows))]
 
+extern crate clap;
+
 use clap::{App, AppSettings, Arg, ErrorKind};
 use std::ffi::OsString;
 use std::os::unix::ffi::OsStringExt;
diff --git a/tests/utils.rs b/tests/utils.rs
deleted file mode 100644
index 295da222..00000000
--- a/tests/utils.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-#![allow(unused_imports, dead_code)]
-
-use std::io::{Cursor, Write};
-use std::str;
-
-use regex::Regex;
-
-use clap::{App, Arg, ArgGroup};
-
-fn compare<S, S2>(l: S, r: S2) -> bool
-where
-    S: AsRef<str>,
-    S2: AsRef<str>,
-{
-    let re = Regex::new("\x1b[^m]*m").unwrap();
-    // Strip out any mismatching \r character on windows that might sneak in on either side
-    let ls = l.as_ref().trim().replace("\r", "");
-    let rs = r.as_ref().trim().replace("\r", "");
-    let left = re.replace_all(&*ls, "");
-    let right = re.replace_all(&*rs, "");
-    let b = left == right;
-    if !b {
-        println!();
-        println!("--> left");
-        println!("{}", left);
-        println!("--> right");
-        println!("{}", right);
-        println!("--")
-    }
-    b
-}
-
-pub fn compare_output(l: App, args: &str, right: &str, stderr: bool) -> bool {
-    let mut buf = Cursor::new(Vec::with_capacity(50));
-    let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
-    let err = res.unwrap_err();
-    err.write_to(&mut buf).unwrap();
-    let content = buf.into_inner();
-    let left = String::from_utf8(content).unwrap();
-    assert_eq!(
-        stderr,
-        err.use_stderr(),
-        "Should Use STDERR failed. Should be {} but is {}",
-        stderr,
-        err.use_stderr()
-    );
-    compare(left, right)
-}
-
-pub fn compare_output2(l: App, args: &str, right1: &str, right2: &str, stderr: bool) -> bool {
-    let mut buf = Cursor::new(Vec::with_capacity(50));
-    let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
-    let err = res.unwrap_err();
-    err.write_to(&mut buf).unwrap();
-    let content = buf.into_inner();
-    let left = String::from_utf8(content).unwrap();
-    assert_eq!(stderr, err.use_stderr());
-    compare(&*left, right1) || compare(&*left, right2)
-}
-
-// Legacy tests from the pyhton script days
-
-pub fn complex_app() -> App<'static> {
-    let opt3_vals = ["fast", "slow"];
-    let pos3_vals = ["vi", "emacs"];
-
-    App::new("clap-test")
-        .version("v1.4.8")
-        .about("tests clap library")
-        .author("Kevin K. <kbknapp@gmail.com>")
-        .arg("-o --option=[opt]... 'tests options'")
-        .arg("[positional] 'tests positionals'")
-        .arg(Arg::from("-f --flag... 'tests flags'").global(true))
-        .args(&[
-            Arg::from("[flag2] -F 'tests flags with exclusions'")
-                .conflicts_with("flag")
-                .requires("long-option-2"),
-            Arg::from("--long-option-2 [option2] 'tests long options with exclusions'")
-                .conflicts_with("option")
-                .requires("positional2"),
-            Arg::from("[positional2] 'tests positionals with exclusions'"),
-            Arg::from("-O --Option [option3] 'specific vals'").possible_values(&opt3_vals),
-            Arg::from("[positional3]... 'tests specific values'").possible_values(&pos3_vals),
-            Arg::from("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
-            Arg::from("--multvalsmo... [one] [two] 'Tests mutliple values, and mult occs'"),
-            Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
-            Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3),
-        ])
-        .subcommand(
-            App::new("subcmd")
-                .about("tests subcommands")
-                .version("0.1")
-                .author("Kevin K. <kbknapp@gmail.com>")
-                .arg("-o --option [scoption]... 'tests options'")
-                .arg("-s --subcmdarg [subcmdarg] 'tests other args'")
-                .arg("[scpositional] 'tests positionals'"),
-        )
-}
diff --git a/tests/version-numbers.rs b/tests/version-numbers.rs
index 6a40558d..411eea54 100644
--- a/tests/version-numbers.rs
+++ b/tests/version-numbers.rs
@@ -1,4 +1,5 @@
-use version_sync::{assert_html_root_url_updated, assert_markdown_deps_updated};
+#[macro_use]
+extern crate version_sync;
 
 #[test]
 fn test_readme_deps() {
diff --git a/tests/version.rs b/tests/version.rs
index 8407b40d..6a934777 100644
--- a/tests/version.rs
+++ b/tests/version.rs
@@ -1,9 +1,12 @@
-mod utils;
+extern crate clap;
+extern crate regex;
 
 use std::str;
 
 use clap::{App, AppSettings, ErrorKind};
 
+include!("../clap-test.rs");
+
 static VERSION: &str = "clap-test v1.4.8";
 
 #[test]
diff --git a/tests/yaml.rs b/tests/yaml.rs
index f211d815..9b9ed64c 100644
--- a/tests/yaml.rs
+++ b/tests/yaml.rs
@@ -1,23 +1,26 @@
 #![cfg(feature = "yaml")]
 
-use clap::{load_yaml, App};
+#[macro_use]
+extern crate clap;
+
+use clap::App;
 
 #[test]
 fn create_app_from_yaml() {
-    let yml = load_yaml!("fixtures/app.yml");
+    let yml = load_yaml!("app.yml");
     App::from(yml);
 }
 
 // TODO: Uncomment to test yaml with 2 spaces https://github.com/chyh1990/yaml-rust/issues/101
 // #[test]
 // fn create_app_from_yaml_2spaces() {
-//     let yml = load_yaml!("fixtures/app_2space.yml");
+//     let yml = load_yaml!("app_2space.yml");
 //     App::from(yml);
 // }
 
 #[test]
 fn help_message() {
-    let yml = load_yaml!("fixtures/app.yml");
+    let yml = load_yaml!("app.yml");
     let mut app = App::from(yml);
     // Generate the full help message!
     let _ = app.try_get_matches_from_mut(Vec::<String>::new());
@@ -32,7 +35,7 @@ fn help_message() {
 
 #[test]
 fn author() {
-    let yml = load_yaml!("fixtures/app.yml");
+    let yml = load_yaml!("app.yml");
     let mut app = App::from(yml);
     // Generate the full help message!
     let _ = app.try_get_matches_from_mut(Vec::<String>::new());