Repository: clap-rs/clap
Pull request #3544 (2022-03-07 20:16:14)

test: Switch completions/man to snapshot testing
Its a bit annoying updating our "output" tests especially when they test irrelevant details, like formatting.  Using snapshot testing make this easier because you can just fix them by running `SNAPSHOTS=overwrite cargo test`.

This is using the core of trycmd to save on building.  This is also why we upgraded trycmd, so they'd be aligned on versions.


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 8cc35be3..381ba9b7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -139,7 +139,7 @@ criterion = "0.3.2"
 trybuild = "1.0.18"
 rustversion = "1"
 # Cutting out `filesystem` feature
-trycmd = { version = "0.12", default-features = false, features = ["color-auto", "diff", "examples"] }
+trycmd = { version = "0.13", default-features = false, features = ["color-auto", "diff", "examples"] }
 
 [[example]]
 name = "demo"
diff --git a/clap_complete/Cargo.toml b/clap_complete/Cargo.toml
index ad28f958..345b6520 100644
--- a/clap_complete/Cargo.toml
+++ b/clap_complete/Cargo.toml
@@ -39,6 +39,7 @@ clap = { path = "../", version = "3.1.0", default-features = false, features = [
 
 [dev-dependencies]
 pretty_assertions = "1.0"
+snapbox = { version = "0.2", features = ["diff"] }
 clap = { path = "../", version = "3.1.0", default-features = false, features = ["std", "derive"] }
 
 [features]
diff --git a/clap_complete_fig/Cargo.toml b/clap_complete_fig/Cargo.toml
index 67b05730..86d4d75f 100644
--- a/clap_complete_fig/Cargo.toml
+++ b/clap_complete_fig/Cargo.toml
@@ -42,4 +42,4 @@ clap = { path = "../", version = "3.1.0", default-features = false, features = [
 clap_complete = { path = "../clap_complete", version = "3.1.0" }
 
 [dev-dependencies]
-pretty_assertions = "1.0"
+snapbox = { version = "0.2", features = ["diff"] }
diff --git a/clap_mangen/Cargo.toml b/clap_mangen/Cargo.toml
index 063341f4..28cc89c9 100644
--- a/clap_mangen/Cargo.toml
+++ b/clap_mangen/Cargo.toml
@@ -39,7 +39,7 @@ roff = "0.2.1"
 clap = { path = "../", version = "3.1", default-features = false, features = ["std", "env"] }
 
 [dev-dependencies]
-pretty_assertions = "1.0"
+snapbox = { version = "0.2", features = ["diff"] }
 clap = { path = "../", version = "3.1", default-features = false, features = ["std"] }
 
 [features]


Test patch:
diff --git a/clap_complete/tests/bash.rs b/clap_complete/tests/bash.rs
new file mode 100644
index 00000000..ac781912
--- /dev/null
+++ b/clap_complete/tests/bash.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.bash.log",
+        clap_complete::shells::Bash,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete/tests/common.rs b/clap_complete/tests/common.rs
new file mode 100644
index 00000000..5d12b4c4
--- /dev/null
+++ b/clap_complete/tests/common.rs
@@ -0,0 +1,235 @@
+pub fn basic_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .arg(clap::Arg::new("config").short('c').global(true))
+        .arg(clap::Arg::new("v").short('v').conflicts_with("config"))
+        .subcommand(
+            clap::Command::new("test")
+                .about("Subcommand")
+                .arg(clap::Arg::new("debug").short('d')),
+        )
+}
+
+pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .propagate_version(true)
+        .about("Tests completions")
+        .arg(
+            clap::Arg::new("file")
+                .value_hint(clap::ValueHint::FilePath)
+                .help("some input file"),
+        )
+        .arg(
+            clap::Arg::new("config")
+                .help("some config file")
+                .short('c')
+                .visible_short_alias('C')
+                .long("config")
+                .visible_alias("conf"),
+        )
+        .arg(clap::Arg::new("choice").possible_values(["first", "second"]))
+        .subcommand(
+            clap::Command::new("test").about("tests things").arg(
+                clap::Arg::new("case")
+                    .long("case")
+                    .takes_value(true)
+                    .help("the case to test"),
+            ),
+        )
+}
+
+pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name)
+        .subcommand(
+            clap::Command::new("some_cmd")
+                .about("tests other things")
+                .arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .help("the other case to test"),
+                ),
+        )
+        .subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
+}
+
+pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .arg(
+            clap::Arg::new("single-quotes")
+                .long("single-quotes")
+                .help("Can be 'always', 'auto', or 'never'"),
+        )
+        .arg(
+            clap::Arg::new("double-quotes")
+                .long("double-quotes")
+                .help("Can be \"always\", \"auto\", or \"never\""),
+        )
+        .arg(
+            clap::Arg::new("backticks")
+                .long("backticks")
+                .help("For more information see `echo test`"),
+        )
+        .arg(
+            clap::Arg::new("backslash")
+                .long("backslash")
+                .help("Avoid '\\n'"),
+        )
+        .arg(
+            clap::Arg::new("brackets")
+                .long("brackets")
+                .help("List packages [filter]"),
+        )
+        .arg(
+            clap::Arg::new("expansions")
+                .long("expansions")
+                .help("Execute the shell command with $SHELL"),
+        )
+        .subcommands([
+            clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
+            clap::Command::new("cmd-double-quotes")
+                .about("Can be \"always\", \"auto\", or \"never\""),
+            clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
+            clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
+            clap::Command::new("cmd-brackets").about("List packages [filter]"),
+            clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
+        ])
+}
+
+pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .about("testing bash completions")
+        .arg(
+            clap::Arg::new("flag")
+                .short('f')
+                .visible_short_alias('F')
+                .long("flag")
+                .visible_alias("flg")
+                .help("cmd flag"),
+        )
+        .arg(
+            clap::Arg::new("option")
+                .short('o')
+                .visible_short_alias('O')
+                .long("option")
+                .visible_alias("opt")
+                .help("cmd option")
+                .takes_value(true),
+        )
+        .arg(clap::Arg::new("positional"))
+}
+
+pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name).subcommand(
+        clap::Command::new("some_cmd")
+            .about("top level subcommand")
+            .subcommand(
+                clap::Command::new("sub_cmd").about("sub-subcommand").arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
+                        .help("the other case to test"),
+                ),
+            ),
+    )
+}
+
+pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .trailing_var_arg(true)
+        .arg(
+            clap::Arg::new("choice")
+                .long("choice")
+                .possible_values(["bash", "fish", "zsh"]),
+        )
+        .arg(
+            clap::Arg::new("unknown")
+                .long("unknown")
+                .value_hint(clap::ValueHint::Unknown),
+        )
+        .arg(
+            clap::Arg::new("other")
+                .long("other")
+                .value_hint(clap::ValueHint::Other),
+        )
+        .arg(
+            clap::Arg::new("path")
+                .long("path")
+                .short('p')
+                .value_hint(clap::ValueHint::AnyPath),
+        )
+        .arg(
+            clap::Arg::new("file")
+                .long("file")
+                .short('f')
+                .value_hint(clap::ValueHint::FilePath),
+        )
+        .arg(
+            clap::Arg::new("dir")
+                .long("dir")
+                .short('d')
+                .value_hint(clap::ValueHint::DirPath),
+        )
+        .arg(
+            clap::Arg::new("exe")
+                .long("exe")
+                .short('e')
+                .value_hint(clap::ValueHint::ExecutablePath),
+        )
+        .arg(
+            clap::Arg::new("cmd_name")
+                .long("cmd-name")
+                .value_hint(clap::ValueHint::CommandName),
+        )
+        .arg(
+            clap::Arg::new("cmd")
+                .long("cmd")
+                .short('c')
+                .value_hint(clap::ValueHint::CommandString),
+        )
+        .arg(
+            clap::Arg::new("command_with_args")
+                .takes_value(true)
+                .multiple_values(true)
+                .value_hint(clap::ValueHint::CommandWithArguments),
+        )
+        .arg(
+            clap::Arg::new("user")
+                .short('u')
+                .long("user")
+                .value_hint(clap::ValueHint::Username),
+        )
+        .arg(
+            clap::Arg::new("host")
+                .short('h')
+                .long("host")
+                .value_hint(clap::ValueHint::Hostname),
+        )
+        .arg(
+            clap::Arg::new("url")
+                .long("url")
+                .value_hint(clap::ValueHint::Url),
+        )
+        .arg(
+            clap::Arg::new("email")
+                .long("email")
+                .value_hint(clap::ValueHint::EmailAddress),
+        )
+}
+
+pub fn assert_matches_path(
+    expected_path: impl AsRef<std::path::Path>,
+    gen: impl clap_complete::Generator,
+    mut cmd: clap::Command,
+    name: &str,
+) {
+    let mut buf = vec![];
+    clap_complete::generate(gen, &mut cmd, name, &mut buf);
+
+    snapbox::Assert::new()
+        .action_env("SNAPSHOTS")
+        .matches_path(expected_path, buf);
+}
diff --git a/clap_complete/tests/completions/bash.rs b/clap_complete/tests/completions/bash.rs
deleted file mode 100644
index 38f443b5..00000000
--- a/clap_complete/tests/completions/bash.rs
+++ /dev/null
@@ -1,331 +0,0 @@
-use super::*;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Tests completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input file"),
-        )
-        .arg(Arg::new("choice").possible_values(["first", "second"]))
-        .subcommand(
-            Command::new("test").about("tests things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("the case to test"),
-            ),
-        )
-}
-
-#[test]
-fn bash() {
-    let mut cmd = build_app();
-    common(Bash, &mut cmd, "myapp", BASH);
-}
-
-static BASH: &str = r#"_myapp() {
-    local i cur prev opts cmds
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-    cmd=""
-    opts=""
-
-    for i in ${COMP_WORDS[@]}
-    do
-        case "${i}" in
-            "$1")
-                cmd="myapp"
-                ;;
-            help)
-                cmd+="__help"
-                ;;
-            test)
-                cmd+="__test"
-                ;;
-            *)
-                ;;
-        esac
-    done
-
-    case "${cmd}" in
-        myapp)
-            opts="-h -V --help --version <file> first second test help"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        myapp__help)
-            opts="<SUBCOMMAND>..."
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        myapp__test)
-            opts="-h -V --case --help --version"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --case)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-    esac
-}
-
-complete -F _myapp -o bashdefault -o default myapp
-"#;
-
-#[test]
-fn bash_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(Bash, &mut cmd, "my_app", BASH_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
-}
-
-static BASH_SPECIAL_CMDS: &str = r#"_my_app() {
-    local i cur prev opts cmds
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-    cmd=""
-    opts=""
-
-    for i in ${COMP_WORDS[@]}
-    do
-        case "${i}" in
-            "$1")
-                cmd="my_app"
-                ;;
-            help)
-                cmd+="__help"
-                ;;
-            some-cmd-with-hyphens)
-                cmd+="__some__cmd__with__hyphens"
-                ;;
-            some_cmd)
-                cmd+="__some_cmd"
-                ;;
-            test)
-                cmd+="__test"
-                ;;
-            *)
-                ;;
-        esac
-    done
-
-    case "${cmd}" in
-        my_app)
-            opts="-h -V --help --version <file> first second test some_cmd some-cmd-with-hyphens help"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        my_app__help)
-            opts="<SUBCOMMAND>..."
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        my_app__some__cmd__with__hyphens)
-            opts="-h -V --help --version"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        my_app__some_cmd)
-            opts="-h -V --config --help --version"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --config)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-        my_app__test)
-            opts="-h -V --case --help --version"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --case)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-    esac
-}
-
-complete -F _my_app -o bashdefault -o default my_app
-"#;
-
-#[test]
-fn bash_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(Bash, &mut cmd, "cmd", BASH_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static BASH_ALIASES: &str = r#"_cmd() {
-    local i cur prev opts cmds
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-    cmd=""
-    opts=""
-
-    for i in ${COMP_WORDS[@]}
-    do
-        case "${i}" in
-            "$1")
-                cmd="cmd"
-                ;;
-            *)
-                ;;
-        esac
-    done
-
-    case "${cmd}" in
-        cmd)
-            opts="-h -V -F -f -O -o --help --version --flg --flag --opt --option <positional>"
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --option)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --opt)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -o)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -O)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-    esac
-}
-
-complete -F _cmd -o bashdefault -o default cmd
-"#;
diff --git a/clap_complete/tests/completions/elvish.rs b/clap_complete/tests/completions/elvish.rs
deleted file mode 100644
index 87d743e7..00000000
--- a/clap_complete/tests/completions/elvish.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-use super::*;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Tests completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input file"),
-        )
-        .subcommand(
-            Command::new("test").about("tests things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("the case to test"),
-            ),
-        )
-}
-
-#[test]
-fn elvish() {
-    let mut cmd = build_app();
-    common(Elvish, &mut cmd, "my_app", ELVISH);
-}
-
-static ELVISH: &str = r#"
-use builtin;
-use str;
-
-set edit:completion:arg-completer[my_app] = {|@words|
-    fn spaces {|n|
-        builtin:repeat $n ' ' | str:join ''
-    }
-    fn cand {|text desc|
-        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    var command = 'my_app'
-    for word $words[1..-1] {
-        if (str:has-prefix $word '-') {
-            break
-        }
-        set command = $command';'$word
-    }
-    var completions = [
-        &'my_app'= {
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-            cand test 'tests things'
-            cand help 'Print this message or the help of the given subcommand(s)'
-        }
-        &'my_app;test'= {
-            cand --case 'the case to test'
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-        }
-        &'my_app;help'= {
-        }
-    ]
-    $completions[$command]
-}
-"#;
-
-#[test]
-fn elvish_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(Elvish, &mut cmd, "my_app", ELVISH_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
-}
-
-static ELVISH_SPECIAL_CMDS: &str = r#"
-use builtin;
-use str;
-
-set edit:completion:arg-completer[my_app] = {|@words|
-    fn spaces {|n|
-        builtin:repeat $n ' ' | str:join ''
-    }
-    fn cand {|text desc|
-        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    var command = 'my_app'
-    for word $words[1..-1] {
-        if (str:has-prefix $word '-') {
-            break
-        }
-        set command = $command';'$word
-    }
-    var completions = [
-        &'my_app'= {
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-            cand test 'tests things'
-            cand some_cmd 'tests other things'
-            cand some-cmd-with-hyphens 'some-cmd-with-hyphens'
-            cand help 'Print this message or the help of the given subcommand(s)'
-        }
-        &'my_app;test'= {
-            cand --case 'the case to test'
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-        }
-        &'my_app;some_cmd'= {
-            cand --config 'the other case to test'
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-        }
-        &'my_app;some-cmd-with-hyphens'= {
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-        }
-        &'my_app;help'= {
-        }
-    ]
-    $completions[$command]
-}
-"#;
-
-#[test]
-fn elvish_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(Elvish, &mut cmd, "cmd", ELVISH_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static ELVISH_ALIASES: &str = r#"
-use builtin;
-use str;
-
-set edit:completion:arg-completer[cmd] = {|@words|
-    fn spaces {|n|
-        builtin:repeat $n ' ' | str:join ''
-    }
-    fn cand {|text desc|
-        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    var command = 'cmd'
-    for word $words[1..-1] {
-        if (str:has-prefix $word '-') {
-            break
-        }
-        set command = $command';'$word
-    }
-    var completions = [
-        &'cmd'= {
-            cand -o 'cmd option'
-            cand -O 'cmd option'
-            cand --option 'cmd option'
-            cand --opt 'cmd option'
-            cand -h 'Print help information'
-            cand --help 'Print help information'
-            cand -V 'Print version information'
-            cand --version 'Print version information'
-            cand -f 'cmd flag'
-            cand -F 'cmd flag'
-            cand --flag 'cmd flag'
-            cand --flg 'cmd flag'
-        }
-    ]
-    $completions[$command]
-}
-"#;
diff --git a/clap_complete/tests/completions/fish.rs b/clap_complete/tests/completions/fish.rs
deleted file mode 100644
index 2ef930e8..00000000
--- a/clap_complete/tests/completions/fish.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-use clap::PossibleValue;
-
-use super::*;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Tests completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input file"),
-        )
-        .subcommand(
-            Command::new("test").about("tests things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("the case to test"),
-            ),
-        )
-}
-
-#[test]
-fn fish() {
-    let mut cmd = build_app();
-    common(Fish, &mut cmd, "myapp", FISH);
-}
-
-static FISH: &str = r#"complete -c myapp -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
-complete -c myapp -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
-complete -c myapp -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
-complete -c myapp -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
-complete -c myapp -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
-complete -c myapp -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
-complete -c myapp -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
-"#;
-
-#[test]
-fn fish_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(Fish, &mut cmd, "my_app", FISH_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
-}
-
-static FISH_SPECIAL_CMDS: &str = r#"complete -c my_app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
-complete -c my_app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'tests other things'
-complete -c my_app -n "__fish_use_subcommand" -f -a "some-cmd-with-hyphens"
-complete -c my_app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
-complete -c my_app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
-complete -c my_app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -l config -d 'the other case to test' -r
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s V -l version -d 'Print version information'
-"#;
-
-#[test]
-fn fish_with_special_help() {
-    let mut cmd = build_app_special_help();
-    common(Fish, &mut cmd, "my_app", FISH_SPECIAL_HELP);
-}
-
-fn build_app_special_help() -> Command<'static> {
-    Command::new("my_app")
-        .version("3.0")
-        .arg(
-            Arg::new("single-quotes")
-                .long("single-quotes")
-                .help("Can be 'always', 'auto', or 'never'"),
-        )
-        .arg(
-            Arg::new("double-quotes")
-                .long("double-quotes")
-                .help("Can be \"always\", \"auto\", or \"never\""),
-        )
-        .arg(
-            Arg::new("backticks")
-                .long("backticks")
-                .help("For more information see `echo test`"),
-        )
-        .arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
-        .arg(
-            Arg::new("brackets")
-                .long("brackets")
-                .help("List packages [filter]"),
-        )
-        .arg(
-            Arg::new("expansions")
-                .long("expansions")
-                .help("Execute the shell command with $SHELL"),
-        )
-}
-
-static FISH_SPECIAL_HELP: &str = r#"complete -c my_app -s h -l help -d 'Print help information'
-complete -c my_app -s V -l version -d 'Print version information'
-complete -c my_app -l single-quotes -d 'Can be \'always\', \'auto\', or \'never\''
-complete -c my_app -l double-quotes -d 'Can be "always", "auto", or "never"'
-complete -c my_app -l backticks -d 'For more information see `echo test`'
-complete -c my_app -l backslash -d 'Avoid \'\\n\''
-complete -c my_app -l brackets -d 'List packages [filter]'
-complete -c my_app -l expansions -d 'Execute the shell command with $SHELL'
-"#;
-
-#[test]
-fn fish_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(Fish, &mut cmd, "cmd", FISH_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static FISH_ALIASES: &str = r#"complete -c cmd -s o -s O -l option -l opt -d 'cmd option' -r
-complete -c cmd -s h -l help -d 'Print help information'
-complete -c cmd -s V -l version -d 'Print version information'
-complete -c cmd -s f -s F -l flag -l flg -d 'cmd flag'
-"#;
-
-#[test]
-fn fish_with_sub_subcommands() {
-    let mut cmd = build_app_sub_subcommands();
-    common(Fish, &mut cmd, "my_app", FISH_SUB_SUBCMDS);
-}
-
-fn build_app_sub_subcommands() -> Command<'static> {
-    build_app_with_name("my_app").subcommand(
-        Command::new("some_cmd")
-            .about("top level subcommand")
-            .subcommand(
-                Command::new("sub_cmd").about("sub-subcommand").arg(
-                    Arg::new("config")
-                        .long("--config")
-                        .takes_value(true)
-                        .possible_values([PossibleValue::new("Lest quotes aren't escaped.")])
-                        .help("the other case to test"),
-                ),
-            ),
-    )
-}
-
-static FISH_SUB_SUBCMDS: &str = r#"complete -c my_app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
-complete -c my_app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'top level subcommand'
-complete -c my_app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
-complete -c my_app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
-complete -c my_app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "sub_cmd" -d 'sub-subcommand'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -l config -d 'the other case to test' -r -f -a "{Lest quotes aren\'t escaped.	}"
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s V -l version -d 'Print version information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
-complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
-"#;
diff --git a/clap_complete/tests/completions/mod.rs b/clap_complete/tests/completions/mod.rs
deleted file mode 100644
index 2f326c47..00000000
--- a/clap_complete/tests/completions/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use clap::{Arg, Command, ValueHint};
-use clap_complete::{generate, shells::*, Generator};
-use std::fmt;
-
-mod bash;
-mod elvish;
-mod fish;
-mod powershell;
-mod zsh;
-
-#[derive(PartialEq, Eq)]
-pub struct PrettyString<'a>(pub &'a str);
-
-impl<'a> fmt::Debug for PrettyString<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write_str(self.0)
-    }
-}
-
-macro_rules! assert_eq {
-    ($left:expr, $right:expr) => {
-        pretty_assertions::assert_eq!(PrettyString($left), PrettyString($right));
-    };
-}
-
-pub fn common<G: Generator>(gen: G, cmd: &mut Command, name: &str, fixture: &str) {
-    let mut buf = vec![];
-    generate(gen, cmd, name, &mut buf);
-    let string = String::from_utf8(buf).unwrap();
-
-    assert_eq!(&string, fixture);
-}
diff --git a/clap_complete/tests/completions/powershell.rs b/clap_complete/tests/completions/powershell.rs
deleted file mode 100644
index 290eeb7d..00000000
--- a/clap_complete/tests/completions/powershell.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-use super::*;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Tests completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input file"),
-        )
-        .arg(
-            Arg::new("config")
-                .help("some config file")
-                .short('c')
-                .visible_short_alias('C')
-                .long("config")
-                .visible_alias("conf"),
-        )
-        .subcommand(
-            Command::new("test").about("tests things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("the case to test"),
-            ),
-        )
-}
-
-#[test]
-fn powershell() {
-    let mut cmd = build_app();
-    common(PowerShell, &mut cmd, "my_app", POWERSHELL);
-}
-
-static POWERSHELL: &str = r#"
-using namespace System.Management.Automation
-using namespace System.Management.Automation.Language
-
-Register-ArgumentCompleter -Native -CommandName 'my_app' -ScriptBlock {
-    param($wordToComplete, $commandAst, $cursorPosition)
-
-    $commandElements = $commandAst.CommandElements
-    $command = @(
-        'my_app'
-        for ($i = 1; $i -lt $commandElements.Count; $i++) {
-            $element = $commandElements[$i]
-            if ($element -isnot [StringConstantExpressionAst] -or
-                $element.StringConstantType -ne [StringConstantType]::BareWord -or
-                $element.Value.StartsWith('-') -or
-                $element.Value -eq $wordToComplete) {
-                break
-        }
-        $element.Value
-    }) -join ';'
-
-    $completions = @(switch ($command) {
-        'my_app' {
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
-            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
-            break
-        }
-        'my_app;test' {
-            [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            break
-        }
-        'my_app;help' {
-            break
-        }
-    })
-
-    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
-        Sort-Object -Property ListItemText
-}
-"#;
-
-#[test]
-fn powershell_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(PowerShell, &mut cmd, "my_app", POWERSHELL_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
-}
-
-static POWERSHELL_SPECIAL_CMDS: &str = r#"
-using namespace System.Management.Automation
-using namespace System.Management.Automation.Language
-
-Register-ArgumentCompleter -Native -CommandName 'my_app' -ScriptBlock {
-    param($wordToComplete, $commandAst, $cursorPosition)
-
-    $commandElements = $commandAst.CommandElements
-    $command = @(
-        'my_app'
-        for ($i = 1; $i -lt $commandElements.Count; $i++) {
-            $element = $commandElements[$i]
-            if ($element -isnot [StringConstantExpressionAst] -or
-                $element.StringConstantType -ne [StringConstantType]::BareWord -or
-                $element.Value.StartsWith('-') -or
-                $element.Value -eq $wordToComplete) {
-                break
-        }
-        $element.Value
-    }) -join ';'
-
-    $completions = @(switch ($command) {
-        'my_app' {
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
-            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
-            [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things')
-            [CompletionResult]::new('some-cmd-with-hyphens', 'some-cmd-with-hyphens', [CompletionResultType]::ParameterValue, 'some-cmd-with-hyphens')
-            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
-            break
-        }
-        'my_app;test' {
-            [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            break
-        }
-        'my_app;some_cmd' {
-            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            break
-        }
-        'my_app;some-cmd-with-hyphens' {
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            break
-        }
-        'my_app;help' {
-            break
-        }
-    })
-
-    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
-        Sort-Object -Property ListItemText
-}
-"#;
-
-#[test]
-fn powershell_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(PowerShell, &mut cmd, "cmd", POWERSHELL_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static POWERSHELL_ALIASES: &str = r#"
-using namespace System.Management.Automation
-using namespace System.Management.Automation.Language
-
-Register-ArgumentCompleter -Native -CommandName 'cmd' -ScriptBlock {
-    param($wordToComplete, $commandAst, $cursorPosition)
-
-    $commandElements = $commandAst.CommandElements
-    $command = @(
-        'cmd'
-        for ($i = 1; $i -lt $commandElements.Count; $i++) {
-            $element = $commandElements[$i]
-            if ($element -isnot [StringConstantExpressionAst] -or
-                $element.StringConstantType -ne [StringConstantType]::BareWord -or
-                $element.Value.StartsWith('-') -or
-                $element.Value -eq $wordToComplete) {
-                break
-        }
-        $element.Value
-    }) -join ';'
-
-    $completions = @(switch ($command) {
-        'cmd' {
-            [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'cmd option')
-            [CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option')
-            [CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option')
-            [CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option')
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
-            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
-            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag')
-            [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag')
-            [CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag')
-            [CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag')
-            break
-        }
-    })
-
-    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
-        Sort-Object -Property ListItemText
-}
-"#;
diff --git a/clap_complete/tests/completions/zsh.rs b/clap_complete/tests/completions/zsh.rs
deleted file mode 100644
index 6bec6195..00000000
--- a/clap_complete/tests/completions/zsh.rs
+++ /dev/null
@@ -1,572 +0,0 @@
-use super::*;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Test test's completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input's file"),
-        )
-        .subcommand(
-            Command::new("test").about("test test's things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("test's cases to test"),
-            ),
-        )
-}
-
-#[test]
-fn zsh() {
-    let mut cmd = build_app();
-    common(Zsh, &mut cmd, "myapp", ZSH);
-}
-
-static ZSH: &str = r#"#compdef myapp
-
-autoload -U is-at-least
-
-_myapp() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-'::file -- some input'\''s file:_files' \
-":: :_myapp_commands" \
-"*::: :->myapp" \
-&& ret=0
-    case $state in
-    (myapp)
-        words=($line[2] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:myapp-command-$line[2]:"
-        case $line[2] in
-            (test)
-_arguments "${_arguments_options[@]}" \
-'--case=[test'\''s cases to test]: : ' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-;;
-(help)
-_arguments "${_arguments_options[@]}" \
-'*::subcommand -- The subcommand whose help message to display:' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-}
-
-(( $+functions[_myapp_commands] )) ||
-_myapp_commands() {
-    local commands; commands=(
-'test:test test'\''s things' \
-'help:Print this message or the help of the given subcommand(s)' \
-    )
-    _describe -t commands 'myapp commands' commands "$@"
-}
-(( $+functions[_myapp__help_commands] )) ||
-_myapp__help_commands() {
-    local commands; commands=()
-    _describe -t commands 'myapp help commands' commands "$@"
-}
-(( $+functions[_myapp__test_commands] )) ||
-_myapp__test_commands() {
-    local commands; commands=()
-    _describe -t commands 'myapp test commands' commands "$@"
-}
-
-_myapp "$@"
-"#;
-
-#[test]
-fn zsh_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(Zsh, &mut cmd, "my_app", ZSH_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hypens").alias("hyphen"))
-        .subcommand(
-            Command::new("some_cmd_with_special_characters")
-                .about("This 'is' a \"special\" [character] string \\"),
-        )
-}
-
-static ZSH_SPECIAL_CMDS: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-'::file -- some input'\''s file:_files' \
-":: :_my_app_commands" \
-"*::: :->my_app" \
-&& ret=0
-    case $state in
-    (my_app)
-        words=($line[2] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:my_app-command-$line[2]:"
-        case $line[2] in
-            (test)
-_arguments "${_arguments_options[@]}" \
-'--case=[test'\''s cases to test]: : ' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-;;
-(some_cmd)
-_arguments "${_arguments_options[@]}" \
-'--config=[the other case to test]: : ' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-;;
-(some-cmd-with-hypens)
-_arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-;;
-(some_cmd_with_special_characters)
-_arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-;;
-(help)
-_arguments "${_arguments_options[@]}" \
-'*::subcommand -- The subcommand whose help message to display:' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=(
-'test:test test'\''s things' \
-'some_cmd:tests other things' \
-'some-cmd-with-hypens:' \
-'some_cmd_with_special_characters:This '\''is'\'' a "special" \[character\] string \\' \
-'help:Print this message or the help of the given subcommand(s)' \
-    )
-    _describe -t commands 'my_app commands' commands "$@"
-}
-(( $+functions[_my_app__help_commands] )) ||
-_my_app__help_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app help commands' commands "$@"
-}
-(( $+functions[_my_app__some-cmd-with-hypens_commands] )) ||
-_my_app__some-cmd-with-hypens_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app some-cmd-with-hypens commands' commands "$@"
-}
-(( $+functions[_my_app__some_cmd_commands] )) ||
-_my_app__some_cmd_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app some_cmd commands' commands "$@"
-}
-(( $+functions[_my_app__some_cmd_with_special_characters_commands] )) ||
-_my_app__some_cmd_with_special_characters_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app some_cmd_with_special_characters commands' commands "$@"
-}
-(( $+functions[_my_app__test_commands] )) ||
-_my_app__test_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app test commands' commands "$@"
-}
-
-_my_app "$@"
-"#;
-
-#[test]
-fn zsh_with_special_help() {
-    let mut cmd = build_app_special_help();
-    common(Zsh, &mut cmd, "my_app", ZSH_SPECIAL_HELP);
-}
-
-fn build_app_special_help() -> Command<'static> {
-    Command::new("my_app")
-        .version("3.0")
-        .arg(
-            Arg::new("single-quotes")
-                .long("single-quotes")
-                .help("Can be 'always', 'auto', or 'never'"),
-        )
-        .arg(
-            Arg::new("double-quotes")
-                .long("double-quotes")
-                .help("Can be \"always\", \"auto\", or \"never\""),
-        )
-        .arg(
-            Arg::new("backticks")
-                .long("backticks")
-                .help("For more information see `echo test`"),
-        )
-        .arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
-        .arg(
-            Arg::new("brackets")
-                .long("brackets")
-                .help("List packages [filter]"),
-        )
-        .arg(
-            Arg::new("expansions")
-                .long("expansions")
-                .help("Execute the shell command with $SHELL"),
-        )
-}
-
-static ZSH_SPECIAL_HELP: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-'--single-quotes[Can be '\''always'\'', '\''auto'\'', or '\''never'\'']' \
-'--double-quotes[Can be "always", "auto", or "never"]' \
-'--backticks[For more information see `echo test`]' \
-'--backslash[Avoid '\''\\n'\'']' \
-'--brackets[List packages \[filter\]]' \
-'--expansions[Execute the shell command with $SHELL]' \
-&& ret=0
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app commands' commands "$@"
-}
-
-_my_app "$@"
-"#;
-
-#[test]
-fn zsh_with_nested_subcommands() {
-    let mut cmd = build_app_nested_subcommands();
-    common(Zsh, &mut cmd, "my_app", ZSH_NESTED_SUBCOMMANDS);
-}
-
-fn build_app_nested_subcommands() -> Command<'static> {
-    Command::new("first")
-        .version("3.0")
-        .subcommand(Command::new("second").subcommand(Command::new("third")))
-}
-
-static ZSH_NESTED_SUBCOMMANDS: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-":: :_my_app_commands" \
-"*::: :->first" \
-&& ret=0
-    case $state in
-    (first)
-        words=($line[1] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:my_app-command-$line[1]:"
-        case $line[1] in
-            (second)
-_arguments "${_arguments_options[@]}" \
-'-h[Print help information]' \
-'--help[Print help information]' \
-":: :_my_app__second_commands" \
-"*::: :->second" \
-&& ret=0
-
-    case $state in
-    (second)
-        words=($line[1] "${words[@]}")
-        (( CURRENT += 1 ))
-        curcontext="${curcontext%:*:*}:my_app-second-command-$line[1]:"
-        case $line[1] in
-            (third)
-_arguments "${_arguments_options[@]}" \
-'--version[Print version information]' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-&& ret=0
-;;
-(help)
-_arguments "${_arguments_options[@]}" \
-'--version[Print version information]' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'*::subcommand -- The subcommand whose help message to display:' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-;;
-(help)
-_arguments "${_arguments_options[@]}" \
-'*::subcommand -- The subcommand whose help message to display:' \
-&& ret=0
-;;
-        esac
-    ;;
-esac
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=(
-'second:' \
-'help:Print this message or the help of the given subcommand(s)' \
-    )
-    _describe -t commands 'my_app commands' commands "$@"
-}
-(( $+functions[_my_app__help_commands] )) ||
-_my_app__help_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app help commands' commands "$@"
-}
-(( $+functions[_my_app__second__help_commands] )) ||
-_my_app__second__help_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app second help commands' commands "$@"
-}
-(( $+functions[_my_app__second_commands] )) ||
-_my_app__second_commands() {
-    local commands; commands=(
-'third:' \
-'help:Print this message or the help of the given subcommand(s)' \
-    )
-    _describe -t commands 'my_app second commands' commands "$@"
-}
-(( $+functions[_my_app__second__third_commands] )) ||
-_my_app__second__third_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app second third commands' commands "$@"
-}
-
-_my_app "$@"
-"#;
-
-#[test]
-fn zsh_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(Zsh, &mut cmd, "cmd", ZSH_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static ZSH_ALIASES: &str = r#"#compdef cmd
-
-autoload -U is-at-least
-
-_cmd() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-o+[cmd option]: : ' \
-'-O+[cmd option]: : ' \
-'--option=[cmd option]: : ' \
-'--opt=[cmd option]: : ' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-'-f[cmd flag]' \
-'-F[cmd flag]' \
-'--flag[cmd flag]' \
-'--flg[cmd flag]' \
-'::positional:' \
-&& ret=0
-}
-
-(( $+functions[_cmd_commands] )) ||
-_cmd_commands() {
-    local commands; commands=()
-    _describe -t commands 'cmd commands' commands "$@"
-}
-
-_cmd "$@"
-"#;
-
-#[test]
-fn zsh_with_files_and_dirs() {
-    let mut cmd = build_app_with_files_and_dirs();
-    common(Zsh, &mut cmd, "my_app", ZSH_PATHS);
-}
-
-fn build_app_with_files_and_dirs() -> Command<'static> {
-    Command::new("my_app")
-        .version("3.0")
-        .about("testing zsh completions")
-        .arg(
-            Arg::new("directory")
-                .long("dir")
-                .help("specify a directory")
-                .value_name("DIR")
-                .number_of_values(3)
-                .value_hint(ValueHint::DirPath),
-        )
-        .arg(
-            Arg::new("file")
-                .long("inputfiles")
-                .value_name("FILE")
-                .multiple_occurrences(true)
-                .help("specify a file")
-                .value_hint(ValueHint::FilePath),
-        )
-}
-
-static ZSH_PATHS: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'--dir=[specify a directory]:DIR:_files -/:DIR:_files -/:DIR:_files -/' \
-'*--inputfiles=[specify a file]:FILE:_files' \
-'-h[Print help information]' \
-'--help[Print help information]' \
-'-V[Print version information]' \
-'--version[Print version information]' \
-&& ret=0
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app commands' commands "$@"
-}
-
-_my_app "$@"
-"#;
diff --git a/clap_complete/tests/elvish.rs b/clap_complete/tests/elvish.rs
new file mode 100644
index 00000000..1f97c4ce
--- /dev/null
+++ b/clap_complete/tests/elvish.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.elvish.log",
+        clap_complete::shells::Elvish,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete/tests/fish.rs b/clap_complete/tests/fish.rs
new file mode 100644
index 00000000..194e7d37
--- /dev/null
+++ b/clap_complete/tests/fish.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.fish.log",
+        clap_complete::shells::Fish,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete/tests/generate_completions.rs b/clap_complete/tests/generate_completions.rs
deleted file mode 100644
index f71ceb35..00000000
--- a/clap_complete/tests/generate_completions.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use std::io;
-
-use clap::{Arg, Command};
-
-use clap_complete::{generate, shells::*};
-
-#[test]
-fn generate_completions() {
-    let mut cmd = Command::new("test_app")
-        .arg(Arg::new("config").short('c').global(true))
-        .arg(Arg::new("v").short('v').conflicts_with("config"))
-        .subcommand(
-            Command::new("test")
-                .about("Subcommand")
-                .arg(Arg::new("debug").short('d')),
-        );
-
-    generate(Bash, &mut cmd, "test_app", &mut io::sink());
-    generate(Fish, &mut cmd, "test_app", &mut io::sink());
-    generate(PowerShell, &mut cmd, "test_app", &mut io::sink());
-    generate(Elvish, &mut cmd, "test_app", &mut io::sink());
-    generate(Zsh, &mut cmd, "test_app", &mut io::sink());
-}
diff --git a/clap_complete/tests/powershell.rs b/clap_complete/tests/powershell.rs
new file mode 100644
index 00000000..07e110b0
--- /dev/null
+++ b/clap_complete/tests/powershell.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.powershell.log",
+        clap_complete::shells::PowerShell,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete/tests/snapshots/aliases.bash.log b/clap_complete/tests/snapshots/aliases.bash.log
new file mode 100644
index 00000000..913dec04
--- /dev/null
+++ b/clap_complete/tests/snapshots/aliases.bash.log
@@ -0,0 +1,54 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -V -F -f -O -o --help --version --flg --flag --opt --option <positional>"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --option)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --opt)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -o)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -O)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/aliases.elvish.log b/clap_complete/tests/snapshots/aliases.elvish.log
new file mode 100644
index 00000000..50853d0b
--- /dev/null
+++ b/clap_complete/tests/snapshots/aliases.elvish.log
@@ -0,0 +1,36 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -o 'cmd option'
+            cand -O 'cmd option'
+            cand --option 'cmd option'
+            cand --opt 'cmd option'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand -f 'cmd flag'
+            cand -F 'cmd flag'
+            cand --flag 'cmd flag'
+            cand --flg 'cmd flag'
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/aliases.fish.log b/clap_complete/tests/snapshots/aliases.fish.log
new file mode 100644
index 00000000..d6c774ae
--- /dev/null
+++ b/clap_complete/tests/snapshots/aliases.fish.log
@@ -0,0 +1,4 @@
+complete -c my-app -s o -s O -l option -l opt -d 'cmd option' -r
+complete -c my-app -s h -l help -d 'Print help information'
+complete -c my-app -s V -l version -d 'Print version information'
+complete -c my-app -s f -s F -l flag -l flg -d 'cmd flag'
diff --git a/clap_complete/tests/snapshots/aliases.powershell.log b/clap_complete/tests/snapshots/aliases.powershell.log
new file mode 100644
index 00000000..e0856f63
--- /dev/null
+++ b/clap_complete/tests/snapshots/aliases.powershell.log
@@ -0,0 +1,42 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'cmd option')
+            [CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option')
+            [CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option')
+            [CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag')
+            [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag')
+            [CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag')
+            [CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag')
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/aliases.zsh.log b/clap_complete/tests/snapshots/aliases.zsh.log
new file mode 100644
index 00000000..d98875ed
--- /dev/null
+++ b/clap_complete/tests/snapshots/aliases.zsh.log
@@ -0,0 +1,40 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-o+[cmd option]: : ' /
+'-O+[cmd option]: : ' /
+'--option=[cmd option]: : ' /
+'--opt=[cmd option]: : ' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'-f[cmd flag]' /
+'-F[cmd flag]' /
+'--flag[cmd flag]' /
+'--flg[cmd flag]' /
+'::positional:' /
+&& ret=0
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/basic.bash.log b/clap_complete/tests/snapshots/basic.bash.log
new file mode 100644
index 00000000..2a5b11c7
--- /dev/null
+++ b/clap_complete/tests/snapshots/basic.bash.log
@@ -0,0 +1,72 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            help)
+                cmd+="__help"
+                ;;
+            test)
+                cmd+="__test"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -c -v --help test help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__help)
+            opts="-c <SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__test)
+            opts="-d -h -c --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/basic.elvish.log b/clap_complete/tests/snapshots/basic.elvish.log
new file mode 100644
index 00000000..195c3596
--- /dev/null
+++ b/clap_complete/tests/snapshots/basic.elvish.log
@@ -0,0 +1,39 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -c 'c'
+            cand -v 'v'
+            cand test 'Subcommand'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;test'= {
+            cand -d 'd'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -c 'c'
+        }
+        &'my-app;help'= {
+            cand -c 'c'
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/basic.fish.log b/clap_complete/tests/snapshots/basic.fish.log
new file mode 100644
index 00000000..5fdf2ce9
--- /dev/null
+++ b/clap_complete/tests/snapshots/basic.fish.log
@@ -0,0 +1,9 @@
+complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_use_subcommand" -s c
+complete -c my-app -n "__fish_use_subcommand" -s v
+complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'Subcommand'
+complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from test" -s d
+complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from test" -s c
+complete -c my-app -n "__fish_seen_subcommand_from help" -s c
diff --git a/clap_complete/tests/snapshots/basic.powershell.log b/clap_complete/tests/snapshots/basic.powershell.log
new file mode 100644
index 00000000..02985edf
--- /dev/null
+++ b/clap_complete/tests/snapshots/basic.powershell.log
@@ -0,0 +1,47 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
+            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'v')
+            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Subcommand')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;test' {
+            [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
+            break
+        }
+        'my-app;help' {
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/basic.zsh.log b/clap_complete/tests/snapshots/basic.zsh.log
new file mode 100644
index 00000000..c1dfe599
--- /dev/null
+++ b/clap_complete/tests/snapshots/basic.zsh.log
@@ -0,0 +1,69 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-c[]' /
+'(-c)-v[]' /
+":: :_my-app_commands" /
+"*::: :->my-app" /
+&& ret=0
+    case $state in
+    (my-app)
+        words=($line[1] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-command-$line[1]:"
+        case $line[1] in
+            (test)
+_arguments "${_arguments_options[@]}" /
+'-d[]' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-c[]' /
+&& ret=0
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'-c[]' /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=(
+'test:Subcommand' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app commands' commands "$@"
+}
+(( $+functions[_my-app__help_commands] )) ||
+_my-app__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app help commands' commands "$@"
+}
+(( $+functions[_my-app__test_commands] )) ||
+_my-app__test_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app test commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/feature_sample.bash.log b/clap_complete/tests/snapshots/feature_sample.bash.log
new file mode 100644
index 00000000..98918ca4
--- /dev/null
+++ b/clap_complete/tests/snapshots/feature_sample.bash.log
@@ -0,0 +1,76 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            help)
+                cmd+="__help"
+                ;;
+            test)
+                cmd+="__test"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -V -C -c --help --version --conf --config <file> first second test help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__help)
+            opts="<SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__test)
+            opts="-h -V --case --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --case)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/feature_sample.elvish.log b/clap_complete/tests/snapshots/feature_sample.elvish.log
new file mode 100644
index 00000000..f4cae420
--- /dev/null
+++ b/clap_complete/tests/snapshots/feature_sample.elvish.log
@@ -0,0 +1,43 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand -c 'some config file'
+            cand -C 'some config file'
+            cand --config 'some config file'
+            cand --conf 'some config file'
+            cand test 'tests things'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;test'= {
+            cand --case 'the case to test'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;help'= {
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/feature_sample.fish.log b/clap_complete/tests/snapshots/feature_sample.fish.log
new file mode 100644
index 00000000..7b5a0e0b
--- /dev/null
+++ b/clap_complete/tests/snapshots/feature_sample.fish.log
@@ -0,0 +1,8 @@
+complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
+complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
+complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
+complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
diff --git a/clap_complete/tests/snapshots/feature_sample.powershell.log b/clap_complete/tests/snapshots/feature_sample.powershell.log
new file mode 100644
index 00000000..b47fd5b4
--- /dev/null
+++ b/clap_complete/tests/snapshots/feature_sample.powershell.log
@@ -0,0 +1,51 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;test' {
+            [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;help' {
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/feature_sample.zsh.log b/clap_complete/tests/snapshots/feature_sample.zsh.log
new file mode 100644
index 00000000..fe943731
--- /dev/null
+++ b/clap_complete/tests/snapshots/feature_sample.zsh.log
@@ -0,0 +1,75 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'-c[some config file]' /
+'-C[some config file]' /
+'--config[some config file]' /
+'--conf[some config file]' /
+'::file -- some input file:_files' /
+'::choice:(first second)' /
+":: :_my-app_commands" /
+"*::: :->my-app" /
+&& ret=0
+    case $state in
+    (my-app)
+        words=($line[3] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
+        case $line[3] in
+            (test)
+_arguments "${_arguments_options[@]}" /
+'--case=[the case to test]: : ' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=(
+'test:tests things' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app commands' commands "$@"
+}
+(( $+functions[_my-app__help_commands] )) ||
+_my-app__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app help commands' commands "$@"
+}
+(( $+functions[_my-app__test_commands] )) ||
+_my-app__test_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app test commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/quoting.bash.log b/clap_complete/tests/snapshots/quoting.bash.log
new file mode 100644
index 00000000..ead2b13b
--- /dev/null
+++ b/clap_complete/tests/snapshots/quoting.bash.log
@@ -0,0 +1,157 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            cmd-backslash)
+                cmd+="__cmd__backslash"
+                ;;
+            cmd-backticks)
+                cmd+="__cmd__backticks"
+                ;;
+            cmd-brackets)
+                cmd+="__cmd__brackets"
+                ;;
+            cmd-double-quotes)
+                cmd+="__cmd__double__quotes"
+                ;;
+            cmd-expansions)
+                cmd+="__cmd__expansions"
+                ;;
+            cmd-single-quotes)
+                cmd+="__cmd__single__quotes"
+                ;;
+            help)
+                cmd+="__help"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -V --help --version --single-quotes --double-quotes --backticks --backslash --brackets --expansions cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__backslash)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__backticks)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__brackets)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__double__quotes)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__expansions)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__cmd__single__quotes)
+            opts="-h --help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__help)
+            opts="<SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/quoting.elvish.log b/clap_complete/tests/snapshots/quoting.elvish.log
new file mode 100644
index 00000000..01242cec
--- /dev/null
+++ b/clap_complete/tests/snapshots/quoting.elvish.log
@@ -0,0 +1,67 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand --single-quotes 'Can be ''always'', ''auto'', or ''never'''
+            cand --double-quotes 'Can be "always", "auto", or "never"'
+            cand --backticks 'For more information see `echo test`'
+            cand --backslash 'Avoid ''/n'''
+            cand --brackets 'List packages [filter]'
+            cand --expansions 'Execute the shell command with $SHELL'
+            cand cmd-single-quotes 'Can be ''always'', ''auto'', or ''never'''
+            cand cmd-double-quotes 'Can be "always", "auto", or "never"'
+            cand cmd-backticks 'For more information see `echo test`'
+            cand cmd-backslash 'Avoid ''/n'''
+            cand cmd-brackets 'List packages [filter]'
+            cand cmd-expansions 'Execute the shell command with $SHELL'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;cmd-single-quotes'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;cmd-double-quotes'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;cmd-backticks'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;cmd-backslash'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;cmd-brackets'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;cmd-expansions'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+        }
+        &'my-app;help'= {
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/quoting.fish.log b/clap_complete/tests/snapshots/quoting.fish.log
new file mode 100644
index 00000000..139a0199
--- /dev/null
+++ b/clap_complete/tests/snapshots/quoting.fish.log
@@ -0,0 +1,21 @@
+complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_use_subcommand" -l single-quotes -d 'Can be /'always/', /'auto/', or /'never/''
+complete -c my-app -n "__fish_use_subcommand" -l double-quotes -d 'Can be "always", "auto", or "never"'
+complete -c my-app -n "__fish_use_subcommand" -l backticks -d 'For more information see `echo test`'
+complete -c my-app -n "__fish_use_subcommand" -l backslash -d 'Avoid /'//n/''
+complete -c my-app -n "__fish_use_subcommand" -l brackets -d 'List packages [filter]'
+complete -c my-app -n "__fish_use_subcommand" -l expansions -d 'Execute the shell command with $SHELL'
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-single-quotes" -d 'Can be /'always/', /'auto/', or /'never/''
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"'
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-backticks" -d 'For more information see `echo test`'
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-backslash" -d 'Avoid /'//n/''
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-brackets" -d 'List packages [filter]'
+complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL'
+complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-single-quotes" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-double-quotes" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-backticks" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-backslash" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-brackets" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from cmd-expansions" -s h -l help -d 'Print help information'
diff --git a/clap_complete/tests/snapshots/quoting.powershell.log b/clap_complete/tests/snapshots/quoting.powershell.log
new file mode 100644
index 00000000..9f4aec8a
--- /dev/null
+++ b/clap_complete/tests/snapshots/quoting.powershell.log
@@ -0,0 +1,80 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--single-quotes', 'single-quotes', [CompletionResultType]::ParameterName, 'Can be ''always'', ''auto'', or ''never''')
+            [CompletionResult]::new('--double-quotes', 'double-quotes', [CompletionResultType]::ParameterName, 'Can be "always", "auto", or "never"')
+            [CompletionResult]::new('--backticks', 'backticks', [CompletionResultType]::ParameterName, 'For more information see `echo test`')
+            [CompletionResult]::new('--backslash', 'backslash', [CompletionResultType]::ParameterName, 'Avoid ''/n''')
+            [CompletionResult]::new('--brackets', 'brackets', [CompletionResultType]::ParameterName, 'List packages [filter]')
+            [CompletionResult]::new('--expansions', 'expansions', [CompletionResultType]::ParameterName, 'Execute the shell command with $SHELL')
+            [CompletionResult]::new('cmd-single-quotes', 'cmd-single-quotes', [CompletionResultType]::ParameterValue, 'Can be ''always'', ''auto'', or ''never''')
+            [CompletionResult]::new('cmd-double-quotes', 'cmd-double-quotes', [CompletionResultType]::ParameterValue, 'Can be "always", "auto", or "never"')
+            [CompletionResult]::new('cmd-backticks', 'cmd-backticks', [CompletionResultType]::ParameterValue, 'For more information see `echo test`')
+            [CompletionResult]::new('cmd-backslash', 'cmd-backslash', [CompletionResultType]::ParameterValue, 'Avoid ''/n''')
+            [CompletionResult]::new('cmd-brackets', 'cmd-brackets', [CompletionResultType]::ParameterValue, 'List packages [filter]')
+            [CompletionResult]::new('cmd-expansions', 'cmd-expansions', [CompletionResultType]::ParameterValue, 'Execute the shell command with $SHELL')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;cmd-single-quotes' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;cmd-double-quotes' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;cmd-backticks' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;cmd-backslash' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;cmd-brackets' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;cmd-expansions' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+        'my-app;help' {
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/quoting.zsh.log b/clap_complete/tests/snapshots/quoting.zsh.log
new file mode 100644
index 00000000..b31471ae
--- /dev/null
+++ b/clap_complete/tests/snapshots/quoting.zsh.log
@@ -0,0 +1,132 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'--single-quotes[Can be '/''always'/'', '/''auto'/'', or '/''never'/'']' /
+'--double-quotes[Can be "always", "auto", or "never"]' /
+'--backticks[For more information see `echo test`]' /
+'--backslash[Avoid '/''//n'/'']' /
+'--brackets[List packages /[filter/]]' /
+'--expansions[Execute the shell command with $SHELL]' /
+":: :_my-app_commands" /
+"*::: :->my-app" /
+&& ret=0
+    case $state in
+    (my-app)
+        words=($line[1] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-command-$line[1]:"
+        case $line[1] in
+            (cmd-single-quotes)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(cmd-double-quotes)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(cmd-backticks)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(cmd-backslash)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(cmd-brackets)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(cmd-expansions)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+&& ret=0
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=(
+'cmd-single-quotes:Can be '/''always'/'', '/''auto'/'', or '/''never'/''' /
+'cmd-double-quotes:Can be "always", "auto", or "never"' /
+'cmd-backticks:For more information see `echo test`' /
+'cmd-backslash:Avoid '/''//n'/''' /
+'cmd-brackets:List packages /[filter/]' /
+'cmd-expansions:Execute the shell command with $SHELL' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-backslash_commands] )) ||
+_my-app__cmd-backslash_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-backslash commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-backticks_commands] )) ||
+_my-app__cmd-backticks_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-backticks commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-brackets_commands] )) ||
+_my-app__cmd-brackets_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-brackets commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-double-quotes_commands] )) ||
+_my-app__cmd-double-quotes_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-double-quotes commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-expansions_commands] )) ||
+_my-app__cmd-expansions_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-expansions commands' commands "$@"
+}
+(( $+functions[_my-app__cmd-single-quotes_commands] )) ||
+_my-app__cmd-single-quotes_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app cmd-single-quotes commands' commands "$@"
+}
+(( $+functions[_my-app__help_commands] )) ||
+_my-app__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app help commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/special_commands.bash.log b/clap_complete/tests/snapshots/special_commands.bash.log
new file mode 100644
index 00000000..27939f0c
--- /dev/null
+++ b/clap_complete/tests/snapshots/special_commands.bash.log
@@ -0,0 +1,114 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            help)
+                cmd+="__help"
+                ;;
+            some-cmd-with-hyphens)
+                cmd+="__some__cmd__with__hyphens"
+                ;;
+            some_cmd)
+                cmd+="__some_cmd"
+                ;;
+            test)
+                cmd+="__test"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -V -C -c --help --version --conf --config <file> first second test some_cmd some-cmd-with-hyphens help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__help)
+            opts="<SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__some__cmd__with__hyphens)
+            opts="-h -V --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__some_cmd)
+            opts="-h -V --config --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --config)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__test)
+            opts="-h -V --case --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --case)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/special_commands.elvish.log b/clap_complete/tests/snapshots/special_commands.elvish.log
new file mode 100644
index 00000000..7ea0e66f
--- /dev/null
+++ b/clap_complete/tests/snapshots/special_commands.elvish.log
@@ -0,0 +1,58 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand -c 'some config file'
+            cand -C 'some config file'
+            cand --config 'some config file'
+            cand --conf 'some config file'
+            cand test 'tests things'
+            cand some_cmd 'tests other things'
+            cand some-cmd-with-hyphens 'some-cmd-with-hyphens'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;test'= {
+            cand --case 'the case to test'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;some_cmd'= {
+            cand --config 'the other case to test'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;some-cmd-with-hyphens'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;help'= {
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/special_commands.fish.log b/clap_complete/tests/snapshots/special_commands.fish.log
new file mode 100644
index 00000000..77d2f5ea
--- /dev/null
+++ b/clap_complete/tests/snapshots/special_commands.fish.log
@@ -0,0 +1,15 @@
+complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
+complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
+complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'tests other things'
+complete -c my-app -n "__fish_use_subcommand" -f -a "some-cmd-with-hyphens"
+complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
+complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -l config -d 'the other case to test' -r
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s V -l version -d 'Print version information'
diff --git a/clap_complete/tests/snapshots/special_commands.powershell.log b/clap_complete/tests/snapshots/special_commands.powershell.log
new file mode 100644
index 00000000..791ec288
--- /dev/null
+++ b/clap_complete/tests/snapshots/special_commands.powershell.log
@@ -0,0 +1,68 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
+            [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things')
+            [CompletionResult]::new('some-cmd-with-hyphens', 'some-cmd-with-hyphens', [CompletionResultType]::ParameterValue, 'some-cmd-with-hyphens')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;test' {
+            [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;some_cmd' {
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;some-cmd-with-hyphens' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;help' {
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/special_commands.zsh.log b/clap_complete/tests/snapshots/special_commands.zsh.log
new file mode 100644
index 00000000..c450097e
--- /dev/null
+++ b/clap_complete/tests/snapshots/special_commands.zsh.log
@@ -0,0 +1,104 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'-c[some config file]' /
+'-C[some config file]' /
+'--config[some config file]' /
+'--conf[some config file]' /
+'::file -- some input file:_files' /
+'::choice:(first second)' /
+":: :_my-app_commands" /
+"*::: :->my-app" /
+&& ret=0
+    case $state in
+    (my-app)
+        words=($line[3] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
+        case $line[3] in
+            (test)
+_arguments "${_arguments_options[@]}" /
+'--case=[the case to test]: : ' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(some_cmd)
+_arguments "${_arguments_options[@]}" /
+'--config=[the other case to test]: : ' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(some-cmd-with-hyphens)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=(
+'test:tests things' /
+'some_cmd:tests other things' /
+'some-cmd-with-hyphens:' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app commands' commands "$@"
+}
+(( $+functions[_my-app__help_commands] )) ||
+_my-app__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app help commands' commands "$@"
+}
+(( $+functions[_my-app__some-cmd-with-hyphens_commands] )) ||
+_my-app__some-cmd-with-hyphens_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app some-cmd-with-hyphens commands' commands "$@"
+}
+(( $+functions[_my-app__some_cmd_commands] )) ||
+_my-app__some_cmd_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app some_cmd commands' commands "$@"
+}
+(( $+functions[_my-app__test_commands] )) ||
+_my-app__test_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app test commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/sub_subcommands.bash.log b/clap_complete/tests/snapshots/sub_subcommands.bash.log
new file mode 100644
index 00000000..dec4d2d7
--- /dev/null
+++ b/clap_complete/tests/snapshots/sub_subcommands.bash.log
@@ -0,0 +1,128 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            help)
+                cmd+="__help"
+                ;;
+            some_cmd)
+                cmd+="__some_cmd"
+                ;;
+            sub_cmd)
+                cmd+="__sub_cmd"
+                ;;
+            test)
+                cmd+="__test"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-h -V -C -c --help --version --conf --config <file> first second test some_cmd help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__help)
+            opts="<SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__some_cmd)
+            opts="-h -V --help --version sub_cmd help"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__some_cmd__help)
+            opts="-h -V --help --version <SUBCOMMAND>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__some_cmd__sub_cmd)
+            opts="-h -V --config --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --config)
+                    COMPREPLY=($(compgen -W "" -- "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+        my__app__test)
+            opts="-h -V --case --help --version"
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --case)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/sub_subcommands.elvish.log b/clap_complete/tests/snapshots/sub_subcommands.elvish.log
new file mode 100644
index 00000000..a096a6c0
--- /dev/null
+++ b/clap_complete/tests/snapshots/sub_subcommands.elvish.log
@@ -0,0 +1,65 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand -c 'some config file'
+            cand -C 'some config file'
+            cand --config 'some config file'
+            cand --conf 'some config file'
+            cand test 'tests things'
+            cand some_cmd 'top level subcommand'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;test'= {
+            cand --case 'the case to test'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;some_cmd'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+            cand sub_cmd 'sub-subcommand'
+            cand help 'Print this message or the help of the given subcommand(s)'
+        }
+        &'my-app;some_cmd;sub_cmd'= {
+            cand --config 'the other case to test'
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;some_cmd;help'= {
+            cand -h 'Print help information'
+            cand --help 'Print help information'
+            cand -V 'Print version information'
+            cand --version 'Print version information'
+        }
+        &'my-app;help'= {
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/sub_subcommands.fish.log b/clap_complete/tests/snapshots/sub_subcommands.fish.log
new file mode 100644
index 00000000..95685111
--- /dev/null
+++ b/clap_complete/tests/snapshots/sub_subcommands.fish.log
@@ -0,0 +1,18 @@
+complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
+complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
+complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'top level subcommand'
+complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
+complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "sub_cmd" -d 'sub-subcommand'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -l config -d 'the other case to test' -r -f -a "{Lest quotes aren/'t escaped.	}"
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s V -l version -d 'Print version information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
+complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
diff --git a/clap_complete/tests/snapshots/sub_subcommands.powershell.log b/clap_complete/tests/snapshots/sub_subcommands.powershell.log
new file mode 100644
index 00000000..a17fe3cc
--- /dev/null
+++ b/clap_complete/tests/snapshots/sub_subcommands.powershell.log
@@ -0,0 +1,76 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
+            [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
+            [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'top level subcommand')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;test' {
+            [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;some_cmd' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('sub_cmd', 'sub_cmd', [CompletionResultType]::ParameterValue, 'sub-subcommand')
+            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
+            break
+        }
+        'my-app;some_cmd;sub_cmd' {
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;some_cmd;help' {
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
+            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
+            break
+        }
+        'my-app;help' {
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/sub_subcommands.zsh.log b/clap_complete/tests/snapshots/sub_subcommands.zsh.log
new file mode 100644
index 00000000..c14f152c
--- /dev/null
+++ b/clap_complete/tests/snapshots/sub_subcommands.zsh.log
@@ -0,0 +1,132 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'-c[some config file]' /
+'-C[some config file]' /
+'--config[some config file]' /
+'--conf[some config file]' /
+'::file -- some input file:_files' /
+'::choice:(first second)' /
+":: :_my-app_commands" /
+"*::: :->my-app" /
+&& ret=0
+    case $state in
+    (my-app)
+        words=($line[3] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
+        case $line[3] in
+            (test)
+_arguments "${_arguments_options[@]}" /
+'--case=[the case to test]: : ' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(some_cmd)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+":: :_my-app__some_cmd_commands" /
+"*::: :->some_cmd" /
+&& ret=0
+
+    case $state in
+    (some_cmd)
+        words=($line[1] "${words[@]}")
+        (( CURRENT += 1 ))
+        curcontext="${curcontext%:*:*}:my-app-some_cmd-command-$line[1]:"
+        case $line[1] in
+            (sub_cmd)
+_arguments "${_arguments_options[@]}" /
+'--config=[the other case to test]: :(Lest quotes aren't escaped.)' /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+&& ret=0
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'-h[Print help information]' /
+'--help[Print help information]' /
+'-V[Print version information]' /
+'--version[Print version information]' /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+;;
+(help)
+_arguments "${_arguments_options[@]}" /
+'*::subcommand -- The subcommand whose help message to display:' /
+&& ret=0
+;;
+        esac
+    ;;
+esac
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=(
+'test:tests things' /
+'some_cmd:top level subcommand' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app commands' commands "$@"
+}
+(( $+functions[_my-app__help_commands] )) ||
+_my-app__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app help commands' commands "$@"
+}
+(( $+functions[_my-app__some_cmd__help_commands] )) ||
+_my-app__some_cmd__help_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app some_cmd help commands' commands "$@"
+}
+(( $+functions[_my-app__some_cmd_commands] )) ||
+_my-app__some_cmd_commands() {
+    local commands; commands=(
+'sub_cmd:sub-subcommand' /
+'help:Print this message or the help of the given subcommand(s)' /
+    )
+    _describe -t commands 'my-app some_cmd commands' commands "$@"
+}
+(( $+functions[_my-app__some_cmd__sub_cmd_commands] )) ||
+_my-app__some_cmd__sub_cmd_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app some_cmd sub_cmd commands' commands "$@"
+}
+(( $+functions[_my-app__test_commands] )) ||
+_my-app__test_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app test commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/snapshots/value_hint.bash.log b/clap_complete/tests/snapshots/value_hint.bash.log
new file mode 100644
index 00000000..4138007a
--- /dev/null
+++ b/clap_complete/tests/snapshots/value_hint.bash.log
@@ -0,0 +1,118 @@
+_my-app() {
+    local i cur prev opts cmds
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD-1]}"
+    cmd=""
+    opts=""
+
+    for i in ${COMP_WORDS[@]}
+    do
+        case "${i}" in
+            "$1")
+                cmd="my__app"
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    case "${cmd}" in
+        my__app)
+            opts="-p -f -d -e -c -u -h --help --choice --unknown --other --path --file --dir --exe --cmd-name --cmd --user --host --url --email <command_with_args>..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --choice)
+                    COMPREPLY=($(compgen -W "" -- "${cur}"))
+                    return 0
+                    ;;
+                --unknown)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --other)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --path)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -p)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --file)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -f)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --dir)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -d)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --exe)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -e)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --cmd-name)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --cmd)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -c)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --user)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -u)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                -h)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --url)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --email)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
+    esac
+}
+
+complete -F _my-app -o bashdefault -o default my-app
diff --git a/clap_complete/tests/snapshots/value_hint.elvish.log b/clap_complete/tests/snapshots/value_hint.elvish.log
new file mode 100644
index 00000000..796647fe
--- /dev/null
+++ b/clap_complete/tests/snapshots/value_hint.elvish.log
@@ -0,0 +1,45 @@
+
+use builtin;
+use str;
+
+set edit:completion:arg-completer[my-app] = {|@words|
+    fn spaces {|n|
+        builtin:repeat $n ' ' | str:join ''
+    }
+    fn cand {|text desc|
+        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
+    }
+    var command = 'my-app'
+    for word $words[1..-1] {
+        if (str:has-prefix $word '-') {
+            break
+        }
+        set command = $command';'$word
+    }
+    var completions = [
+        &'my-app'= {
+            cand --choice 'choice'
+            cand --unknown 'unknown'
+            cand --other 'other'
+            cand -p 'p'
+            cand --path 'path'
+            cand -f 'f'
+            cand --file 'file'
+            cand -d 'd'
+            cand --dir 'dir'
+            cand -e 'e'
+            cand --exe 'exe'
+            cand --cmd-name 'cmd-name'
+            cand -c 'c'
+            cand --cmd 'cmd'
+            cand -u 'u'
+            cand --user 'user'
+            cand -h 'h'
+            cand --host 'host'
+            cand --url 'url'
+            cand --email 'email'
+            cand --help 'Print help information'
+        }
+    ]
+    $completions[$command]
+}
diff --git a/clap_complete/tests/snapshots/value_hint.fish.log b/clap_complete/tests/snapshots/value_hint.fish.log
new file mode 100644
index 00000000..e98b3bd5
--- /dev/null
+++ b/clap_complete/tests/snapshots/value_hint.fish.log
@@ -0,0 +1,14 @@
+complete -c my-app -l choice -r -f -a "{bash	,fish	,zsh	}"
+complete -c my-app -l unknown -r
+complete -c my-app -l other -r -f
+complete -c my-app -s p -l path -r -F
+complete -c my-app -s f -l file -r -F
+complete -c my-app -s d -l dir -r -f -a "(__fish_complete_directories)"
+complete -c my-app -s e -l exe -r -F
+complete -c my-app -l cmd-name -r -f -a "(__fish_complete_command)"
+complete -c my-app -s c -l cmd -r -f -a "(__fish_complete_command)"
+complete -c my-app -s u -l user -r -f -a "(__fish_complete_users)"
+complete -c my-app -s h -l host -r -f -a "(__fish_print_hostnames)"
+complete -c my-app -l url -r -f
+complete -c my-app -l email -r -f
+complete -c my-app -l help -d 'Print help information'
diff --git a/clap_complete/tests/snapshots/value_hint.powershell.log b/clap_complete/tests/snapshots/value_hint.powershell.log
new file mode 100644
index 00000000..7389d268
--- /dev/null
+++ b/clap_complete/tests/snapshots/value_hint.powershell.log
@@ -0,0 +1,51 @@
+
+using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+
+Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        'my-app'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-') -or
+                $element.Value -eq $wordToComplete) {
+                break
+        }
+        $element.Value
+    }) -join ';'
+
+    $completions = @(switch ($command) {
+        'my-app' {
+            [CompletionResult]::new('--choice', 'choice', [CompletionResultType]::ParameterName, 'choice')
+            [CompletionResult]::new('--unknown', 'unknown', [CompletionResultType]::ParameterName, 'unknown')
+            [CompletionResult]::new('--other', 'other', [CompletionResultType]::ParameterName, 'other')
+            [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'p')
+            [CompletionResult]::new('--path', 'path', [CompletionResultType]::ParameterName, 'path')
+            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'f')
+            [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'file')
+            [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd')
+            [CompletionResult]::new('--dir', 'dir', [CompletionResultType]::ParameterName, 'dir')
+            [CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'e')
+            [CompletionResult]::new('--exe', 'exe', [CompletionResultType]::ParameterName, 'exe')
+            [CompletionResult]::new('--cmd-name', 'cmd-name', [CompletionResultType]::ParameterName, 'cmd-name')
+            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
+            [CompletionResult]::new('--cmd', 'cmd', [CompletionResultType]::ParameterName, 'cmd')
+            [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u')
+            [CompletionResult]::new('--user', 'user', [CompletionResultType]::ParameterName, 'user')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'h')
+            [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host')
+            [CompletionResult]::new('--url', 'url', [CompletionResultType]::ParameterName, 'url')
+            [CompletionResult]::new('--email', 'email', [CompletionResultType]::ParameterName, 'email')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
+            break
+        }
+    })
+
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}
diff --git a/clap_complete/tests/snapshots/value_hint.zsh.log b/clap_complete/tests/snapshots/value_hint.zsh.log
new file mode 100644
index 00000000..1bb1411e
--- /dev/null
+++ b/clap_complete/tests/snapshots/value_hint.zsh.log
@@ -0,0 +1,49 @@
+#compdef my-app
+
+autoload -U is-at-least
+
+_my-app() {
+    typeset -A opt_args
+    typeset -a _arguments_options
+    local ret=1
+
+    if is-at-least 5.2; then
+        _arguments_options=(-s -S -C)
+    else
+        _arguments_options=(-s -C)
+    fi
+
+    local context curcontext="$curcontext" state line
+    _arguments "${_arguments_options[@]}" /
+'--choice=[]: :(bash fish zsh)' /
+'--unknown=[]: : ' /
+'--other=[]: :( )' /
+'-p+[]: :_files' /
+'--path=[]: :_files' /
+'-f+[]: :_files' /
+'--file=[]: :_files' /
+'-d+[]: :_files -/' /
+'--dir=[]: :_files -/' /
+'-e+[]: :_absolute_command_paths' /
+'--exe=[]: :_absolute_command_paths' /
+'--cmd-name=[]: :_command_names -e' /
+'-c+[]: :_cmdstring' /
+'--cmd=[]: :_cmdstring' /
+'-u+[]: :_users' /
+'--user=[]: :_users' /
+'-h+[]: :_hosts' /
+'--host=[]: :_hosts' /
+'--url=[]: :_urls' /
+'--email=[]: :_email_addresses' /
+'--help[Print help information]' /
+'*::command_with_args:_cmdambivalent' /
+&& ret=0
+}
+
+(( $+functions[_my-app_commands] )) ||
+_my-app_commands() {
+    local commands; commands=()
+    _describe -t commands 'my-app commands' commands "$@"
+}
+
+_my-app "$@"
diff --git a/clap_complete/tests/value_hints.rs b/clap_complete/tests/value_hints.rs
deleted file mode 100644
index 55ea9af6..00000000
--- a/clap_complete/tests/value_hints.rs
+++ /dev/null
@@ -1,160 +0,0 @@
-mod completions;
-
-use clap::{Arg, Command, ValueHint};
-
-use clap_complete::shells::*;
-use completions::common;
-
-pub fn build_app_with_value_hints() -> Command<'static> {
-    Command::new("my_app")
-        .trailing_var_arg(true)
-        .arg(
-            Arg::new("choice")
-                .long("choice")
-                .possible_values(["bash", "fish", "zsh"]),
-        )
-        .arg(
-            Arg::new("unknown")
-                .long("unknown")
-                .value_hint(ValueHint::Unknown),
-        )
-        .arg(Arg::new("other").long("other").value_hint(ValueHint::Other))
-        .arg(
-            Arg::new("path")
-                .long("path")
-                .short('p')
-                .value_hint(ValueHint::AnyPath),
-        )
-        .arg(
-            Arg::new("file")
-                .long("file")
-                .short('f')
-                .value_hint(ValueHint::FilePath),
-        )
-        .arg(
-            Arg::new("dir")
-                .long("dir")
-                .short('d')
-                .value_hint(ValueHint::DirPath),
-        )
-        .arg(
-            Arg::new("exe")
-                .long("exe")
-                .short('e')
-                .value_hint(ValueHint::ExecutablePath),
-        )
-        .arg(
-            Arg::new("cmd_name")
-                .long("cmd-name")
-                .value_hint(ValueHint::CommandName),
-        )
-        .arg(
-            Arg::new("cmd")
-                .long("cmd")
-                .short('c')
-                .value_hint(ValueHint::CommandString),
-        )
-        .arg(
-            Arg::new("command_with_args")
-                .takes_value(true)
-                .multiple_values(true)
-                .value_hint(ValueHint::CommandWithArguments),
-        )
-        .arg(
-            Arg::new("user")
-                .short('u')
-                .long("user")
-                .value_hint(ValueHint::Username),
-        )
-        .arg(
-            Arg::new("host")
-                .short('h')
-                .long("host")
-                .value_hint(ValueHint::Hostname),
-        )
-        .arg(Arg::new("url").long("url").value_hint(ValueHint::Url))
-        .arg(
-            Arg::new("email")
-                .long("email")
-                .value_hint(ValueHint::EmailAddress),
-        )
-}
-
-static ZSH_VALUE_HINTS: &str = r#"#compdef my_app
-
-autoload -U is-at-least
-
-_my_app() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'--choice=[]: :(bash fish zsh)' \
-'--unknown=[]: : ' \
-'--other=[]: :( )' \
-'-p+[]: :_files' \
-'--path=[]: :_files' \
-'-f+[]: :_files' \
-'--file=[]: :_files' \
-'-d+[]: :_files -/' \
-'--dir=[]: :_files -/' \
-'-e+[]: :_absolute_command_paths' \
-'--exe=[]: :_absolute_command_paths' \
-'--cmd-name=[]: :_command_names -e' \
-'-c+[]: :_cmdstring' \
-'--cmd=[]: :_cmdstring' \
-'-u+[]: :_users' \
-'--user=[]: :_users' \
-'-h+[]: :_hosts' \
-'--host=[]: :_hosts' \
-'--url=[]: :_urls' \
-'--email=[]: :_email_addresses' \
-'--help[Print help information]' \
-'*::command_with_args:_cmdambivalent' \
-&& ret=0
-}
-
-(( $+functions[_my_app_commands] )) ||
-_my_app_commands() {
-    local commands; commands=()
-    _describe -t commands 'my_app commands' commands "$@"
-}
-
-_my_app "$@"
-"#;
-
-static FISH_VALUE_HINTS: &str = r#"complete -c my_app -l choice -r -f -a "{bash	,fish	,zsh	}"
-complete -c my_app -l unknown -r
-complete -c my_app -l other -r -f
-complete -c my_app -s p -l path -r -F
-complete -c my_app -s f -l file -r -F
-complete -c my_app -s d -l dir -r -f -a "(__fish_complete_directories)"
-complete -c my_app -s e -l exe -r -F
-complete -c my_app -l cmd-name -r -f -a "(__fish_complete_command)"
-complete -c my_app -s c -l cmd -r -f -a "(__fish_complete_command)"
-complete -c my_app -s u -l user -r -f -a "(__fish_complete_users)"
-complete -c my_app -s h -l host -r -f -a "(__fish_print_hostnames)"
-complete -c my_app -l url -r -f
-complete -c my_app -l email -r -f
-complete -c my_app -l help -d 'Print help information'
-"#;
-
-#[test]
-fn zsh_with_value_hints() {
-    let mut cmd = build_app_with_value_hints();
-    common(Zsh, &mut cmd, "my_app", ZSH_VALUE_HINTS);
-}
-
-#[test]
-fn fish_with_value_hints() {
-    let mut cmd = build_app_with_value_hints();
-    common(Fish, &mut cmd, "my_app", FISH_VALUE_HINTS);
-}
diff --git a/clap_complete/tests/zsh.rs b/clap_complete/tests/zsh.rs
new file mode 100644
index 00000000..e29a31c4
--- /dev/null
+++ b/clap_complete/tests/zsh.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.zsh.log",
+        clap_complete::shells::Zsh,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete_fig/tests/common.rs b/clap_complete_fig/tests/common.rs
new file mode 100644
index 00000000..5d12b4c4
--- /dev/null
+++ b/clap_complete_fig/tests/common.rs
@@ -0,0 +1,235 @@
+pub fn basic_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .arg(clap::Arg::new("config").short('c').global(true))
+        .arg(clap::Arg::new("v").short('v').conflicts_with("config"))
+        .subcommand(
+            clap::Command::new("test")
+                .about("Subcommand")
+                .arg(clap::Arg::new("debug").short('d')),
+        )
+}
+
+pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .propagate_version(true)
+        .about("Tests completions")
+        .arg(
+            clap::Arg::new("file")
+                .value_hint(clap::ValueHint::FilePath)
+                .help("some input file"),
+        )
+        .arg(
+            clap::Arg::new("config")
+                .help("some config file")
+                .short('c')
+                .visible_short_alias('C')
+                .long("config")
+                .visible_alias("conf"),
+        )
+        .arg(clap::Arg::new("choice").possible_values(["first", "second"]))
+        .subcommand(
+            clap::Command::new("test").about("tests things").arg(
+                clap::Arg::new("case")
+                    .long("case")
+                    .takes_value(true)
+                    .help("the case to test"),
+            ),
+        )
+}
+
+pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name)
+        .subcommand(
+            clap::Command::new("some_cmd")
+                .about("tests other things")
+                .arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .help("the other case to test"),
+                ),
+        )
+        .subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
+}
+
+pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .arg(
+            clap::Arg::new("single-quotes")
+                .long("single-quotes")
+                .help("Can be 'always', 'auto', or 'never'"),
+        )
+        .arg(
+            clap::Arg::new("double-quotes")
+                .long("double-quotes")
+                .help("Can be \"always\", \"auto\", or \"never\""),
+        )
+        .arg(
+            clap::Arg::new("backticks")
+                .long("backticks")
+                .help("For more information see `echo test`"),
+        )
+        .arg(
+            clap::Arg::new("backslash")
+                .long("backslash")
+                .help("Avoid '\\n'"),
+        )
+        .arg(
+            clap::Arg::new("brackets")
+                .long("brackets")
+                .help("List packages [filter]"),
+        )
+        .arg(
+            clap::Arg::new("expansions")
+                .long("expansions")
+                .help("Execute the shell command with $SHELL"),
+        )
+        .subcommands([
+            clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
+            clap::Command::new("cmd-double-quotes")
+                .about("Can be \"always\", \"auto\", or \"never\""),
+            clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
+            clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
+            clap::Command::new("cmd-brackets").about("List packages [filter]"),
+            clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
+        ])
+}
+
+pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .about("testing bash completions")
+        .arg(
+            clap::Arg::new("flag")
+                .short('f')
+                .visible_short_alias('F')
+                .long("flag")
+                .visible_alias("flg")
+                .help("cmd flag"),
+        )
+        .arg(
+            clap::Arg::new("option")
+                .short('o')
+                .visible_short_alias('O')
+                .long("option")
+                .visible_alias("opt")
+                .help("cmd option")
+                .takes_value(true),
+        )
+        .arg(clap::Arg::new("positional"))
+}
+
+pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name).subcommand(
+        clap::Command::new("some_cmd")
+            .about("top level subcommand")
+            .subcommand(
+                clap::Command::new("sub_cmd").about("sub-subcommand").arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
+                        .help("the other case to test"),
+                ),
+            ),
+    )
+}
+
+pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .trailing_var_arg(true)
+        .arg(
+            clap::Arg::new("choice")
+                .long("choice")
+                .possible_values(["bash", "fish", "zsh"]),
+        )
+        .arg(
+            clap::Arg::new("unknown")
+                .long("unknown")
+                .value_hint(clap::ValueHint::Unknown),
+        )
+        .arg(
+            clap::Arg::new("other")
+                .long("other")
+                .value_hint(clap::ValueHint::Other),
+        )
+        .arg(
+            clap::Arg::new("path")
+                .long("path")
+                .short('p')
+                .value_hint(clap::ValueHint::AnyPath),
+        )
+        .arg(
+            clap::Arg::new("file")
+                .long("file")
+                .short('f')
+                .value_hint(clap::ValueHint::FilePath),
+        )
+        .arg(
+            clap::Arg::new("dir")
+                .long("dir")
+                .short('d')
+                .value_hint(clap::ValueHint::DirPath),
+        )
+        .arg(
+            clap::Arg::new("exe")
+                .long("exe")
+                .short('e')
+                .value_hint(clap::ValueHint::ExecutablePath),
+        )
+        .arg(
+            clap::Arg::new("cmd_name")
+                .long("cmd-name")
+                .value_hint(clap::ValueHint::CommandName),
+        )
+        .arg(
+            clap::Arg::new("cmd")
+                .long("cmd")
+                .short('c')
+                .value_hint(clap::ValueHint::CommandString),
+        )
+        .arg(
+            clap::Arg::new("command_with_args")
+                .takes_value(true)
+                .multiple_values(true)
+                .value_hint(clap::ValueHint::CommandWithArguments),
+        )
+        .arg(
+            clap::Arg::new("user")
+                .short('u')
+                .long("user")
+                .value_hint(clap::ValueHint::Username),
+        )
+        .arg(
+            clap::Arg::new("host")
+                .short('h')
+                .long("host")
+                .value_hint(clap::ValueHint::Hostname),
+        )
+        .arg(
+            clap::Arg::new("url")
+                .long("url")
+                .value_hint(clap::ValueHint::Url),
+        )
+        .arg(
+            clap::Arg::new("email")
+                .long("email")
+                .value_hint(clap::ValueHint::EmailAddress),
+        )
+}
+
+pub fn assert_matches_path(
+    expected_path: impl AsRef<std::path::Path>,
+    gen: impl clap_complete::Generator,
+    mut cmd: clap::Command,
+    name: &str,
+) {
+    let mut buf = vec![];
+    clap_complete::generate(gen, &mut cmd, name, &mut buf);
+
+    snapbox::Assert::new()
+        .action_env("SNAPSHOTS")
+        .matches_path(expected_path, buf);
+}
diff --git a/clap_complete_fig/tests/completions/fig.rs b/clap_complete_fig/tests/completions/fig.rs
deleted file mode 100644
index e06790b9..00000000
--- a/clap_complete_fig/tests/completions/fig.rs
+++ /dev/null
@@ -1,477 +0,0 @@
-use super::*;
-use crate::Fig;
-
-fn build_app() -> Command<'static> {
-    build_app_with_name("myapp")
-}
-
-fn build_app_with_name(s: &'static str) -> Command<'static> {
-    Command::new(s)
-        .version("3.0")
-        .propagate_version(true)
-        .about("Tests completions")
-        .arg(
-            Arg::new("file")
-                .value_hint(ValueHint::FilePath)
-                .help("some input file"),
-        )
-        .subcommand(
-            Command::new("test").about("tests things").arg(
-                Arg::new("case")
-                    .long("case")
-                    .takes_value(true)
-                    .help("the case to test"),
-            ),
-        )
-}
-
-#[test]
-fn fig() {
-    let mut cmd = build_app();
-    common(Fig, &mut cmd, "myapp", FIG);
-}
-
-static FIG: &str = r#"const completion: Fig.Spec = {
-  name: "myapp",
-  description: "Tests completions",
-  subcommands: [
-    {
-      name: "test",
-      description: "tests things",
-      options: [
-        {
-          name: "--case",
-          description: "the case to test",
-          args: {
-            name: "case",
-            isOptional: true,
-          },
-        },
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "help",
-      description: "Print this message or the help of the given subcommand(s)",
-      options: [
-      ],
-      args: {
-        name: "subcommand",
-        isOptional: true,
-      },
-    },
-  ],
-  options: [
-    {
-      name: ["-h", "--help"],
-      description: "Print help information",
-    },
-    {
-      name: ["-V", "--version"],
-      description: "Print version information",
-    },
-  ],
-  args: {
-    name: "file",
-    isOptional: true,
-    template: "filepaths",
-  },
-};
-
-export default completion;
-"#;
-
-#[test]
-fn fig_with_special_commands() {
-    let mut cmd = build_app_special_commands();
-    common(Fig, &mut cmd, "my_app", FIG_SPECIAL_CMDS);
-}
-
-fn build_app_special_commands() -> Command<'static> {
-    build_app_with_name("my_app")
-        .subcommand(
-            Command::new("some_cmd").about("tests other things").arg(
-                Arg::new("config")
-                    .long("--config")
-                    .takes_value(true)
-                    .help("the other case to test"),
-            ),
-        )
-        .subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
-}
-
-static FIG_SPECIAL_CMDS: &str = r#"const completion: Fig.Spec = {
-  name: "my_app",
-  description: "Tests completions",
-  subcommands: [
-    {
-      name: "test",
-      description: "tests things",
-      options: [
-        {
-          name: "--case",
-          description: "the case to test",
-          args: {
-            name: "case",
-            isOptional: true,
-          },
-        },
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "some_cmd",
-      description: "tests other things",
-      options: [
-        {
-          name: "--config",
-          description: "the other case to test",
-          args: {
-            name: "config",
-            isOptional: true,
-          },
-        },
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "some-cmd-with-hyphens",
-      options: [
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "help",
-      description: "Print this message or the help of the given subcommand(s)",
-      options: [
-      ],
-      args: {
-        name: "subcommand",
-        isOptional: true,
-      },
-    },
-  ],
-  options: [
-    {
-      name: ["-h", "--help"],
-      description: "Print help information",
-    },
-    {
-      name: ["-V", "--version"],
-      description: "Print version information",
-    },
-  ],
-  args: {
-    name: "file",
-    isOptional: true,
-    template: "filepaths",
-  },
-};
-
-export default completion;
-"#;
-
-#[test]
-fn fig_with_special_help() {
-    let mut cmd = build_app_special_help();
-    common(Fig, &mut cmd, "my_app", FIG_SPECIAL_HELP);
-}
-
-fn build_app_special_help() -> Command<'static> {
-    Command::new("my_app")
-        .version("3.0")
-        .arg(
-            Arg::new("single-quotes")
-                .long("single-quotes")
-                .help("Can be 'always', 'auto', or 'never'"),
-        )
-        .arg(
-            Arg::new("double-quotes")
-                .long("double-quotes")
-                .help("Can be \"always\", \"auto\", or \"never\""),
-        )
-        .arg(
-            Arg::new("backticks")
-                .long("backticks")
-                .help("For more information see `echo test`"),
-        )
-        .arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
-        .arg(
-            Arg::new("brackets")
-                .long("brackets")
-                .help("List packages [filter]"),
-        )
-        .arg(
-            Arg::new("expansions")
-                .long("expansions")
-                .help("Execute the shell command with $SHELL"),
-        )
-}
-
-static FIG_SPECIAL_HELP: &str = r#"const completion: Fig.Spec = {
-  name: "my_app",
-  description: "",
-  options: [
-    {
-      name: ["-h", "--help"],
-      description: "Print help information",
-    },
-    {
-      name: ["-V", "--version"],
-      description: "Print version information",
-    },
-    {
-      name: "--single-quotes",
-      description: "Can be 'always', 'auto', or 'never'",
-    },
-    {
-      name: "--double-quotes",
-      description: "Can be \"always\", \"auto\", or \"never\"",
-    },
-    {
-      name: "--backticks",
-      description: "For more information see `echo test`",
-    },
-    {
-      name: "--backslash",
-      description: "Avoid '\\n'",
-    },
-    {
-      name: "--brackets",
-      description: "List packages [filter]",
-    },
-    {
-      name: "--expansions",
-      description: "Execute the shell command with $SHELL",
-    },
-  ],
-};
-
-export default completion;
-"#;
-
-#[test]
-fn fig_with_aliases() {
-    let mut cmd = build_app_with_aliases();
-    common(Fig, &mut cmd, "cmd", FIG_ALIASES);
-}
-
-fn build_app_with_aliases() -> Command<'static> {
-    Command::new("cmd")
-        .version("3.0")
-        .about("testing bash completions")
-        .arg(
-            Arg::new("flag")
-                .short('f')
-                .visible_short_alias('F')
-                .long("flag")
-                .visible_alias("flg")
-                .help("cmd flag"),
-        )
-        .arg(
-            Arg::new("option")
-                .short('o')
-                .visible_short_alias('O')
-                .long("option")
-                .visible_alias("opt")
-                .help("cmd option")
-                .takes_value(true),
-        )
-        .arg(Arg::new("positional"))
-}
-
-static FIG_ALIASES: &str = r#"const completion: Fig.Spec = {
-  name: "cmd",
-  description: "testing bash completions",
-  options: [
-    {
-      name: ["-o", "-O", "--option", "--opt"],
-      description: "cmd option",
-      args: {
-        name: "option",
-        isOptional: true,
-      },
-    },
-    {
-      name: ["-h", "--help"],
-      description: "Print help information",
-    },
-    {
-      name: ["-V", "--version"],
-      description: "Print version information",
-    },
-    {
-      name: ["-f", "-F", "--flag", "--flg"],
-      description: "cmd flag",
-    },
-  ],
-  args: {
-    name: "positional",
-    isOptional: true,
-  },
-};
-
-export default completion;
-"#;
-
-#[test]
-fn fig_with_sub_subcommands() {
-    let mut cmd = build_app_sub_subcommands();
-    common(Fig, &mut cmd, "my_app", FIG_SUB_SUBCMDS);
-}
-
-fn build_app_sub_subcommands() -> Command<'static> {
-    build_app_with_name("my_app").subcommand(
-        Command::new("some_cmd")
-            .about("top level subcommand")
-            .subcommand(
-                Command::new("sub_cmd").about("sub-subcommand").arg(
-                    Arg::new("config")
-                        .long("--config")
-                        .takes_value(true)
-                        .help("the other case to test"),
-                ),
-            ),
-    )
-}
-
-static FIG_SUB_SUBCMDS: &str = r#"const completion: Fig.Spec = {
-  name: "my_app",
-  description: "Tests completions",
-  subcommands: [
-    {
-      name: "test",
-      description: "tests things",
-      options: [
-        {
-          name: "--case",
-          description: "the case to test",
-          args: {
-            name: "case",
-            isOptional: true,
-          },
-        },
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "some_cmd",
-      description: "top level subcommand",
-      subcommands: [
-        {
-          name: "sub_cmd",
-          description: "sub-subcommand",
-          options: [
-            {
-              name: "--config",
-              description: "the other case to test",
-              args: {
-                name: "config",
-                isOptional: true,
-              },
-            },
-            {
-              name: ["-h", "--help"],
-              description: "Print help information",
-            },
-            {
-              name: ["-V", "--version"],
-              description: "Print version information",
-            },
-          ],
-        },
-        {
-          name: "help",
-          description: "Print this message or the help of the given subcommand(s)",
-          options: [
-            {
-              name: ["-h", "--help"],
-              description: "Print help information",
-            },
-            {
-              name: ["-V", "--version"],
-              description: "Print version information",
-            },
-          ],
-          args: {
-            name: "subcommand",
-            isOptional: true,
-          },
-        },
-      ],
-      options: [
-        {
-          name: ["-h", "--help"],
-          description: "Print help information",
-        },
-        {
-          name: ["-V", "--version"],
-          description: "Print version information",
-        },
-      ],
-    },
-    {
-      name: "help",
-      description: "Print this message or the help of the given subcommand(s)",
-      options: [
-      ],
-      args: {
-        name: "subcommand",
-        isOptional: true,
-      },
-    },
-  ],
-  options: [
-    {
-      name: ["-h", "--help"],
-      description: "Print help information",
-    },
-    {
-      name: ["-V", "--version"],
-      description: "Print version information",
-    },
-  ],
-  args: {
-    name: "file",
-    isOptional: true,
-    template: "filepaths",
-  },
-};
-
-export default completion;
-"#;
diff --git a/clap_complete_fig/tests/completions/mod.rs b/clap_complete_fig/tests/completions/mod.rs
deleted file mode 100644
index 4368c063..00000000
--- a/clap_complete_fig/tests/completions/mod.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use clap::{Arg, Command, ValueHint};
-use clap_complete::{generate, Generator};
-use std::fmt;
-
-mod fig;
-
-#[derive(PartialEq, Eq)]
-pub struct PrettyString<'a>(pub &'a str);
-
-impl<'a> fmt::Debug for PrettyString<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write_str(self.0)
-    }
-}
-
-macro_rules! assert_eq {
-    ($left:expr, $right:expr) => {
-        pretty_assertions::assert_eq!(PrettyString($left), PrettyString($right));
-    };
-}
-
-pub fn common<G: Generator>(gen: G, cmd: &mut Command, name: &str, fixture: &str) {
-    let mut buf = vec![];
-    generate(gen, cmd, name, &mut buf);
-    let string = String::from_utf8(buf).unwrap();
-
-    assert_eq!(&string, fixture);
-}
diff --git a/clap_complete_fig/tests/fig.rs b/clap_complete_fig/tests/fig.rs
new file mode 100644
index 00000000..d93db7c8
--- /dev/null
+++ b/clap_complete_fig/tests/fig.rs
@@ -0,0 +1,85 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/basic.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/feature_sample.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/special_commands.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/quoting.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/aliases.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/sub_subcommands.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path(
+        "tests/snapshots/value_hint.fig.js",
+        clap_complete_fig::Fig,
+        cmd,
+        name,
+    );
+}
diff --git a/clap_complete_fig/tests/generate_completions.rs b/clap_complete_fig/tests/generate_completions.rs
deleted file mode 100644
index 99a7f665..00000000
--- a/clap_complete_fig/tests/generate_completions.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use clap::{Arg, Command};
-use clap_complete::generate;
-use clap_complete_fig::Fig;
-use std::io;
-
-#[test]
-fn generate_completions() {
-    let mut cmd = Command::new("test_app")
-        .arg(Arg::new("config").short('c').global(true))
-        .arg(Arg::new("v").short('v').conflicts_with("config"))
-        .subcommand(
-            Command::new("test")
-                .about("Subcommand")
-                .arg(Arg::new("debug").short('d')),
-        );
-
-    generate(Fig, &mut cmd, "test_app", &mut io::sink());
-}
diff --git a/clap_complete_fig/tests/snapshots/aliases.fig.js b/clap_complete_fig/tests/snapshots/aliases.fig.js
new file mode 100644
index 00000000..16f61717
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/aliases.fig.js
@@ -0,0 +1,32 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "testing bash completions",
+  options: [
+    {
+      name: ["-o", "-O", "--option", "--opt"],
+      description: "cmd option",
+      args: {
+        name: "option",
+        isOptional: true,
+      },
+    },
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: ["-V", "--version"],
+      description: "Print version information",
+    },
+    {
+      name: ["-f", "-F", "--flag", "--flg"],
+      description: "cmd flag",
+    },
+  ],
+  args: {
+    name: "positional",
+    isOptional: true,
+  },
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/basic.fig.js b/clap_complete_fig/tests/snapshots/basic.fig.js
new file mode 100644
index 00000000..4bcc271f
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/basic.fig.js
@@ -0,0 +1,49 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "",
+  subcommands: [
+    {
+      name: "test",
+      description: "Subcommand",
+      options: [
+        {
+          name: "-d",
+        },
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: "-c",
+        },
+      ],
+    },
+    {
+      name: "help",
+      description: "Print this message or the help of the given subcommand(s)",
+      options: [
+        {
+          name: "-c",
+        },
+      ],
+      args: {
+        name: "subcommand",
+        isOptional: true,
+      },
+    },
+  ],
+  options: [
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: "-c",
+    },
+    {
+      name: "-v",
+    },
+  ],
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/feature_sample.fig.js b/clap_complete_fig/tests/snapshots/feature_sample.fig.js
new file mode 100644
index 00000000..5d69d01a
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/feature_sample.fig.js
@@ -0,0 +1,73 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "Tests completions",
+  subcommands: [
+    {
+      name: "test",
+      description: "tests things",
+      options: [
+        {
+          name: "--case",
+          description: "the case to test",
+          args: {
+            name: "case",
+            isOptional: true,
+          },
+        },
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "help",
+      description: "Print this message or the help of the given subcommand(s)",
+      options: [
+      ],
+      args: {
+        name: "subcommand",
+        isOptional: true,
+      },
+    },
+  ],
+  options: [
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: ["-V", "--version"],
+      description: "Print version information",
+    },
+    {
+      name: ["-c", "-C", "--config", "--conf"],
+      description: "some config file",
+    },
+  ],
+  args: [
+{
+    name: "file",
+    isOptional: true,
+    template: "filepaths",
+  },
+{
+    name: "choice",
+    isOptional: true,
+    suggestions: [
+      {
+        name: "first",
+      },
+      {
+        name: "second",
+      },
+    ]
+  },
+  ]
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/quoting.fig.js b/clap_complete_fig/tests/snapshots/quoting.fig.js
new file mode 100644
index 00000000..89cd2528
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/quoting.fig.js
@@ -0,0 +1,112 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "",
+  subcommands: [
+    {
+      name: "cmd-single-quotes",
+      description: "Can be 'always', 'auto', or 'never'",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "cmd-double-quotes",
+      description: "Can be /"always/", /"auto/", or /"never/"",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "cmd-backticks",
+      description: "For more information see `echo test`",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "cmd-backslash",
+      description: "Avoid '//n'",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "cmd-brackets",
+      description: "List packages [filter]",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "cmd-expansions",
+      description: "Execute the shell command with $SHELL",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+      ],
+    },
+    {
+      name: "help",
+      description: "Print this message or the help of the given subcommand(s)",
+      options: [
+      ],
+      args: {
+        name: "subcommand",
+        isOptional: true,
+      },
+    },
+  ],
+  options: [
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: ["-V", "--version"],
+      description: "Print version information",
+    },
+    {
+      name: "--single-quotes",
+      description: "Can be 'always', 'auto', or 'never'",
+    },
+    {
+      name: "--double-quotes",
+      description: "Can be /"always/", /"auto/", or /"never/"",
+    },
+    {
+      name: "--backticks",
+      description: "For more information see `echo test`",
+    },
+    {
+      name: "--backslash",
+      description: "Avoid '//n'",
+    },
+    {
+      name: "--brackets",
+      description: "List packages [filter]",
+    },
+    {
+      name: "--expansions",
+      description: "Execute the shell command with $SHELL",
+    },
+  ],
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/special_commands.fig.js b/clap_complete_fig/tests/snapshots/special_commands.fig.js
new file mode 100644
index 00000000..3ae3da48
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/special_commands.fig.js
@@ -0,0 +1,108 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "Tests completions",
+  subcommands: [
+    {
+      name: "test",
+      description: "tests things",
+      options: [
+        {
+          name: "--case",
+          description: "the case to test",
+          args: {
+            name: "case",
+            isOptional: true,
+          },
+        },
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "some_cmd",
+      description: "tests other things",
+      options: [
+        {
+          name: "--config",
+          description: "the other case to test",
+          args: {
+            name: "config",
+            isOptional: true,
+          },
+        },
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "some-cmd-with-hyphens",
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "help",
+      description: "Print this message or the help of the given subcommand(s)",
+      options: [
+      ],
+      args: {
+        name: "subcommand",
+        isOptional: true,
+      },
+    },
+  ],
+  options: [
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: ["-V", "--version"],
+      description: "Print version information",
+    },
+    {
+      name: ["-c", "-C", "--config", "--conf"],
+      description: "some config file",
+    },
+  ],
+  args: [
+{
+    name: "file",
+    isOptional: true,
+    template: "filepaths",
+  },
+{
+    name: "choice",
+    isOptional: true,
+    suggestions: [
+      {
+        name: "first",
+      },
+      {
+        name: "second",
+      },
+    ]
+  },
+  ]
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js b/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js
new file mode 100644
index 00000000..4f3a8a98
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js
@@ -0,0 +1,134 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "Tests completions",
+  subcommands: [
+    {
+      name: "test",
+      description: "tests things",
+      options: [
+        {
+          name: "--case",
+          description: "the case to test",
+          args: {
+            name: "case",
+            isOptional: true,
+          },
+        },
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "some_cmd",
+      description: "top level subcommand",
+      subcommands: [
+        {
+          name: "sub_cmd",
+          description: "sub-subcommand",
+          options: [
+            {
+              name: "--config",
+              description: "the other case to test",
+              args: {
+                name: "config",
+                isOptional: true,
+                suggestions: [
+                  {
+                    name: "Lest quotes aren't escaped.",
+                  },
+                ]
+              },
+            },
+            {
+              name: ["-h", "--help"],
+              description: "Print help information",
+            },
+            {
+              name: ["-V", "--version"],
+              description: "Print version information",
+            },
+          ],
+        },
+        {
+          name: "help",
+          description: "Print this message or the help of the given subcommand(s)",
+          options: [
+            {
+              name: ["-h", "--help"],
+              description: "Print help information",
+            },
+            {
+              name: ["-V", "--version"],
+              description: "Print version information",
+            },
+          ],
+          args: {
+            name: "subcommand",
+            isOptional: true,
+          },
+        },
+      ],
+      options: [
+        {
+          name: ["-h", "--help"],
+          description: "Print help information",
+        },
+        {
+          name: ["-V", "--version"],
+          description: "Print version information",
+        },
+      ],
+    },
+    {
+      name: "help",
+      description: "Print this message or the help of the given subcommand(s)",
+      options: [
+      ],
+      args: {
+        name: "subcommand",
+        isOptional: true,
+      },
+    },
+  ],
+  options: [
+    {
+      name: ["-h", "--help"],
+      description: "Print help information",
+    },
+    {
+      name: ["-V", "--version"],
+      description: "Print version information",
+    },
+    {
+      name: ["-c", "-C", "--config", "--conf"],
+      description: "some config file",
+    },
+  ],
+  args: [
+{
+    name: "file",
+    isOptional: true,
+    template: "filepaths",
+  },
+{
+    name: "choice",
+    isOptional: true,
+    suggestions: [
+      {
+        name: "first",
+      },
+      {
+        name: "second",
+      },
+    ]
+  },
+  ]
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/snapshots/value_hint.fig.js b/clap_complete_fig/tests/snapshots/value_hint.fig.js
new file mode 100644
index 00000000..9fe463d8
--- /dev/null
+++ b/clap_complete_fig/tests/snapshots/value_hint.fig.js
@@ -0,0 +1,126 @@
+const completion: Fig.Spec = {
+  name: "my-app",
+  description: "",
+  options: [
+    {
+      name: "--choice",
+      args: {
+        name: "choice",
+        isOptional: true,
+        suggestions: [
+          {
+            name: "bash",
+          },
+          {
+            name: "fish",
+          },
+          {
+            name: "zsh",
+          },
+        ]
+      },
+    },
+    {
+      name: "--unknown",
+      args: {
+        name: "unknown",
+        isOptional: true,
+      },
+    },
+    {
+      name: "--other",
+      args: {
+        name: "other",
+        isOptional: true,
+      },
+    },
+    {
+      name: ["-p", "--path"],
+      args: {
+        name: "path",
+        isOptional: true,
+        template: "filepaths",
+      },
+    },
+    {
+      name: ["-f", "--file"],
+      args: {
+        name: "file",
+        isOptional: true,
+        template: "filepaths",
+      },
+    },
+    {
+      name: ["-d", "--dir"],
+      args: {
+        name: "dir",
+        isOptional: true,
+        template: "folders",
+      },
+    },
+    {
+      name: ["-e", "--exe"],
+      args: {
+        name: "exe",
+        isOptional: true,
+        template: "filepaths",
+      },
+    },
+    {
+      name: "--cmd-name",
+      args: {
+        name: "cmd_name",
+        isOptional: true,
+        isCommand: true,
+      },
+    },
+    {
+      name: ["-c", "--cmd"],
+      args: {
+        name: "cmd",
+        isOptional: true,
+        isCommand: true,
+      },
+    },
+    {
+      name: ["-u", "--user"],
+      args: {
+        name: "user",
+        isOptional: true,
+      },
+    },
+    {
+      name: ["-h", "--host"],
+      args: {
+        name: "host",
+        isOptional: true,
+      },
+    },
+    {
+      name: "--url",
+      args: {
+        name: "url",
+        isOptional: true,
+      },
+    },
+    {
+      name: "--email",
+      args: {
+        name: "email",
+        isOptional: true,
+      },
+    },
+    {
+      name: "--help",
+      description: "Print help information",
+    },
+  ],
+  args: {
+    name: "command_with_args",
+    isVariadic: true,
+    isOptional: true,
+    isCommand: true,
+  },
+};
+
+export default completion;
diff --git a/clap_complete_fig/tests/value_hints.rs b/clap_complete_fig/tests/value_hints.rs
deleted file mode 100644
index 08388f08..00000000
--- a/clap_complete_fig/tests/value_hints.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-use clap::{Arg, Command, ValueHint};
-use clap_complete_fig::Fig;
-use completions::common;
-
-mod completions;
-
-pub fn build_app_with_value_hints() -> Command<'static> {
-    Command::new("my_app")
-        .disable_version_flag(true)
-        .trailing_var_arg(true)
-        .arg(
-            Arg::new("choice")
-                .long("choice")
-                .possible_values(["bash", "fish", "zsh"]),
-        )
-        .arg(
-            Arg::new("unknown")
-                .long("unknown")
-                .value_hint(ValueHint::Unknown),
-        )
-        .arg(Arg::new("other").long("other").value_hint(ValueHint::Other))
-        .arg(
-            Arg::new("path")
-                .long("path")
-                .short('p')
-                .value_hint(ValueHint::AnyPath),
-        )
-        .arg(
-            Arg::new("file")
-                .long("file")
-                .short('f')
-                .value_hint(ValueHint::FilePath),
-        )
-        .arg(
-            Arg::new("dir")
-                .long("dir")
-                .short('d')
-                .value_hint(ValueHint::DirPath),
-        )
-        .arg(
-            Arg::new("exe")
-                .long("exe")
-                .short('e')
-                .value_hint(ValueHint::ExecutablePath),
-        )
-        .arg(
-            Arg::new("cmd_name")
-                .long("cmd-name")
-                .value_hint(ValueHint::CommandName),
-        )
-        .arg(
-            Arg::new("cmd")
-                .long("cmd")
-                .short('c')
-                .value_hint(ValueHint::CommandString),
-        )
-        .arg(
-            Arg::new("command_with_args")
-                .takes_value(true)
-                .multiple_values(true)
-                .value_hint(ValueHint::CommandWithArguments),
-        )
-        .arg(
-            Arg::new("user")
-                .short('u')
-                .long("user")
-                .value_hint(ValueHint::Username),
-        )
-        .arg(
-            Arg::new("host")
-                .short('h')
-                .long("host")
-                .value_hint(ValueHint::Hostname),
-        )
-        .arg(Arg::new("url").long("url").value_hint(ValueHint::Url))
-        .arg(
-            Arg::new("email")
-                .long("email")
-                .value_hint(ValueHint::EmailAddress),
-        )
-}
-
-static FIG_VALUE_HINTS: &str = r#"const completion: Fig.Spec = {
-  name: "my_app",
-  description: "",
-  options: [
-    {
-      name: "--choice",
-      args: {
-        name: "choice",
-        isOptional: true,
-        suggestions: [
-          {
-            name: "bash",
-          },
-          {
-            name: "fish",
-          },
-          {
-            name: "zsh",
-          },
-        ]
-      },
-    },
-    {
-      name: "--unknown",
-      args: {
-        name: "unknown",
-        isOptional: true,
-      },
-    },
-    {
-      name: "--other",
-      args: {
-        name: "other",
-        isOptional: true,
-      },
-    },
-    {
-      name: ["-p", "--path"],
-      args: {
-        name: "path",
-        isOptional: true,
-        template: "filepaths",
-      },
-    },
-    {
-      name: ["-f", "--file"],
-      args: {
-        name: "file",
-        isOptional: true,
-        template: "filepaths",
-      },
-    },
-    {
-      name: ["-d", "--dir"],
-      args: {
-        name: "dir",
-        isOptional: true,
-        template: "folders",
-      },
-    },
-    {
-      name: ["-e", "--exe"],
-      args: {
-        name: "exe",
-        isOptional: true,
-        template: "filepaths",
-      },
-    },
-    {
-      name: "--cmd-name",
-      args: {
-        name: "cmd_name",
-        isOptional: true,
-        isCommand: true,
-      },
-    },
-    {
-      name: ["-c", "--cmd"],
-      args: {
-        name: "cmd",
-        isOptional: true,
-        isCommand: true,
-      },
-    },
-    {
-      name: ["-u", "--user"],
-      args: {
-        name: "user",
-        isOptional: true,
-      },
-    },
-    {
-      name: ["-h", "--host"],
-      args: {
-        name: "host",
-        isOptional: true,
-      },
-    },
-    {
-      name: "--url",
-      args: {
-        name: "url",
-        isOptional: true,
-      },
-    },
-    {
-      name: "--email",
-      args: {
-        name: "email",
-        isOptional: true,
-      },
-    },
-    {
-      name: "--help",
-      description: "Print help information",
-    },
-  ],
-  args: {
-    name: "command_with_args",
-    isVariadic: true,
-    isOptional: true,
-    isCommand: true,
-  },
-};
-
-export default completion;
-"#;
-
-#[test]
-fn fig_with_value_hints() {
-    let mut cmd = build_app_with_value_hints();
-    common(Fig, &mut cmd, "my_app", FIG_VALUE_HINTS);
-}
diff --git a/clap_mangen/tests/common.rs b/clap_mangen/tests/common.rs
new file mode 100644
index 00000000..52f0e7f3
--- /dev/null
+++ b/clap_mangen/tests/common.rs
@@ -0,0 +1,230 @@
+pub fn basic_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .arg(clap::Arg::new("config").short('c').global(true))
+        .arg(clap::Arg::new("v").short('v').conflicts_with("config"))
+        .subcommand(
+            clap::Command::new("test")
+                .about("Subcommand")
+                .arg(clap::Arg::new("debug").short('d')),
+        )
+}
+
+pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .propagate_version(true)
+        .about("Tests completions")
+        .arg(
+            clap::Arg::new("file")
+                .value_hint(clap::ValueHint::FilePath)
+                .help("some input file"),
+        )
+        .arg(
+            clap::Arg::new("config")
+                .help("some config file")
+                .short('c')
+                .visible_short_alias('C')
+                .long("config")
+                .visible_alias("conf"),
+        )
+        .arg(clap::Arg::new("choice").possible_values(["first", "second"]))
+        .subcommand(
+            clap::Command::new("test").about("tests things").arg(
+                clap::Arg::new("case")
+                    .long("case")
+                    .takes_value(true)
+                    .help("the case to test"),
+            ),
+        )
+}
+
+pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name)
+        .subcommand(
+            clap::Command::new("some_cmd")
+                .about("tests other things")
+                .arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .help("the other case to test"),
+                ),
+        )
+        .subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
+}
+
+pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .arg(
+            clap::Arg::new("single-quotes")
+                .long("single-quotes")
+                .help("Can be 'always', 'auto', or 'never'"),
+        )
+        .arg(
+            clap::Arg::new("double-quotes")
+                .long("double-quotes")
+                .help("Can be \"always\", \"auto\", or \"never\""),
+        )
+        .arg(
+            clap::Arg::new("backticks")
+                .long("backticks")
+                .help("For more information see `echo test`"),
+        )
+        .arg(
+            clap::Arg::new("backslash")
+                .long("backslash")
+                .help("Avoid '\\n'"),
+        )
+        .arg(
+            clap::Arg::new("brackets")
+                .long("brackets")
+                .help("List packages [filter]"),
+        )
+        .arg(
+            clap::Arg::new("expansions")
+                .long("expansions")
+                .help("Execute the shell command with $SHELL"),
+        )
+        .subcommands([
+            clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
+            clap::Command::new("cmd-double-quotes")
+                .about("Can be \"always\", \"auto\", or \"never\""),
+            clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
+            clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
+            clap::Command::new("cmd-brackets").about("List packages [filter]"),
+            clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
+        ])
+}
+
+pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .version("3.0")
+        .about("testing bash completions")
+        .arg(
+            clap::Arg::new("flag")
+                .short('f')
+                .visible_short_alias('F')
+                .long("flag")
+                .visible_alias("flg")
+                .help("cmd flag"),
+        )
+        .arg(
+            clap::Arg::new("option")
+                .short('o')
+                .visible_short_alias('O')
+                .long("option")
+                .visible_alias("opt")
+                .help("cmd option")
+                .takes_value(true),
+        )
+        .arg(clap::Arg::new("positional"))
+}
+
+pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
+    feature_sample_command(name).subcommand(
+        clap::Command::new("some_cmd")
+            .about("top level subcommand")
+            .subcommand(
+                clap::Command::new("sub_cmd").about("sub-subcommand").arg(
+                    clap::Arg::new("config")
+                        .long("--config")
+                        .takes_value(true)
+                        .possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
+                        .help("the other case to test"),
+                ),
+            ),
+    )
+}
+
+pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
+    clap::Command::new(name)
+        .trailing_var_arg(true)
+        .arg(
+            clap::Arg::new("choice")
+                .long("choice")
+                .possible_values(["bash", "fish", "zsh"]),
+        )
+        .arg(
+            clap::Arg::new("unknown")
+                .long("unknown")
+                .value_hint(clap::ValueHint::Unknown),
+        )
+        .arg(
+            clap::Arg::new("other")
+                .long("other")
+                .value_hint(clap::ValueHint::Other),
+        )
+        .arg(
+            clap::Arg::new("path")
+                .long("path")
+                .short('p')
+                .value_hint(clap::ValueHint::AnyPath),
+        )
+        .arg(
+            clap::Arg::new("file")
+                .long("file")
+                .short('f')
+                .value_hint(clap::ValueHint::FilePath),
+        )
+        .arg(
+            clap::Arg::new("dir")
+                .long("dir")
+                .short('d')
+                .value_hint(clap::ValueHint::DirPath),
+        )
+        .arg(
+            clap::Arg::new("exe")
+                .long("exe")
+                .short('e')
+                .value_hint(clap::ValueHint::ExecutablePath),
+        )
+        .arg(
+            clap::Arg::new("cmd_name")
+                .long("cmd-name")
+                .value_hint(clap::ValueHint::CommandName),
+        )
+        .arg(
+            clap::Arg::new("cmd")
+                .long("cmd")
+                .short('c')
+                .value_hint(clap::ValueHint::CommandString),
+        )
+        .arg(
+            clap::Arg::new("command_with_args")
+                .takes_value(true)
+                .multiple_values(true)
+                .value_hint(clap::ValueHint::CommandWithArguments),
+        )
+        .arg(
+            clap::Arg::new("user")
+                .short('u')
+                .long("user")
+                .value_hint(clap::ValueHint::Username),
+        )
+        .arg(
+            clap::Arg::new("host")
+                .short('h')
+                .long("host")
+                .value_hint(clap::ValueHint::Hostname),
+        )
+        .arg(
+            clap::Arg::new("url")
+                .long("url")
+                .value_hint(clap::ValueHint::Url),
+        )
+        .arg(
+            clap::Arg::new("email")
+                .long("email")
+                .value_hint(clap::ValueHint::EmailAddress),
+        )
+}
+
+pub fn assert_matches_path(expected_path: impl AsRef<std::path::Path>, cmd: clap::Command) {
+    let mut buf = vec![];
+    clap_mangen::Man::new(cmd).render(&mut buf).unwrap();
+
+    snapbox::Assert::new()
+        .action_env("SNAPSHOTS")
+        .matches_path(expected_path, buf);
+}
diff --git a/clap_mangen/tests/generate.rs b/clap_mangen/tests/generate.rs
deleted file mode 100644
index c8a2a1ab..00000000
--- a/clap_mangen/tests/generate.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use clap::{arg, Command};
-use clap_mangen::Man;
-use std::io;
-
-#[test]
-fn render_manpage() {
-    let cmd = Command::new("myapp")
-        .version("1.0")
-        .author("Kevin K. <kbknapp@gmail.com>")
-        .about("Does awesome things")
-        .long_about("With a longer description to help clarify some things.")
-        .after_help("This is an extra section added to the end of the manpage.")
-        .after_long_help("With even more text added.")
-        .arg(
-            arg!(-c --config <FILE> "Sets a custom config file")
-                .long_help("Some more text about how to set a custom config file")
-                .required(false)
-                .takes_value(true),
-        )
-        .arg(arg!([output] "Sets an optional output file").index(1))
-        .arg(arg!(-d --debug ... "Turn debugging information on"))
-        .subcommand(
-            Command::new("test")
-                .about("does testing things")
-                .arg(arg!(-l --list "Lists test values")),
-        );
-
-    Man::new(cmd).render(&mut io::sink()).unwrap();
-}
diff --git a/clap_mangen/tests/roff.rs b/clap_mangen/tests/roff.rs
new file mode 100644
index 00000000..3770dd1c
--- /dev/null
+++ b/clap_mangen/tests/roff.rs
@@ -0,0 +1,50 @@
+mod common;
+
+#[test]
+fn basic() {
+    let name = "my-app";
+    let cmd = common::basic_command(name);
+    common::assert_matches_path("tests/snapshots/basic.bash.roff", cmd);
+}
+
+#[test]
+fn feature_sample() {
+    let name = "my-app";
+    let cmd = common::feature_sample_command(name);
+    common::assert_matches_path("tests/snapshots/feature_sample.bash.roff", cmd);
+}
+
+#[test]
+fn special_commands() {
+    let name = "my-app";
+    let cmd = common::special_commands_command(name);
+    common::assert_matches_path("tests/snapshots/special_commands.bash.roff", cmd);
+}
+
+#[test]
+fn quoting() {
+    let name = "my-app";
+    let cmd = common::quoting_command(name);
+    common::assert_matches_path("tests/snapshots/quoting.bash.roff", cmd);
+}
+
+#[test]
+fn aliases() {
+    let name = "my-app";
+    let cmd = common::aliases_command(name);
+    common::assert_matches_path("tests/snapshots/aliases.bash.roff", cmd);
+}
+
+#[test]
+fn sub_subcommands() {
+    let name = "my-app";
+    let cmd = common::sub_subcommands_command(name);
+    common::assert_matches_path("tests/snapshots/sub_subcommands.bash.roff", cmd);
+}
+
+#[test]
+fn value_hint() {
+    let name = "my-app";
+    let cmd = common::value_hint_command(name);
+    common::assert_matches_path("tests/snapshots/value_hint.bash.roff", cmd);
+}
diff --git a/clap_mangen/tests/snapshots/aliases.bash.roff b/clap_mangen/tests/snapshots/aliases.bash.roff
new file mode 100644
index 00000000..313f0578
--- /dev/null
+++ b/clap_mangen/tests/snapshots/aliases.bash.roff
@@ -0,0 +1,26 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app 3.0" 
+.SH NAME
+my/-app /- testing bash completions
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-f/fR|/fB/-/-flag/fR] [/fB/-o/fR|/fB/-/-option/fR] [/fIpositional/fR] 
+.SH DESCRIPTION
+testing bash completions
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-V/fR, /fB/-/-version/fR
+Print version information
+.TP
+/fB/-f/fR, /fB/-/-flag/fR
+cmd flag
+.TP
+/fB/-o/fR, /fB/-/-option/fR
+cmd option
+.TP
+
+.SH VERSION
+v3.0
diff --git a/clap_mangen/tests/snapshots/basic.bash.roff b/clap_mangen/tests/snapshots/basic.bash.roff
new file mode 100644
index 00000000..94da963b
--- /dev/null
+++ b/clap_mangen/tests/snapshots/basic.bash.roff
@@ -0,0 +1,25 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app " 
+.SH NAME
+my/-app
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-c /fR] [/fB/-v /fR] [/fIsubcommands/fR]
+.SH DESCRIPTION
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-c/fR
+
+.TP
+/fB/-v/fR
+
+.SH SUBCOMMANDS
+.TP
+my/-app/-test(1)
+Subcommand
+.TP
+my/-app/-help(1)
+Print this message or the help of the given subcommand(s)
diff --git a/clap_mangen/tests/snapshots/feature_sample.bash.roff b/clap_mangen/tests/snapshots/feature_sample.bash.roff
new file mode 100644
index 00000000..3b7802a9
--- /dev/null
+++ b/clap_mangen/tests/snapshots/feature_sample.bash.roff
@@ -0,0 +1,32 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app 3.0" 
+.SH NAME
+my/-app /- Tests completions
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
+.SH DESCRIPTION
+Tests completions
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-V/fR, /fB/-/-version/fR
+Print version information
+.TP
+/fB/-c/fR, /fB/-/-config/fR
+some config file
+.TP
+some input file
+.TP
+
+.SH SUBCOMMANDS
+.TP
+my/-app/-test(1)
+tests things
+.TP
+my/-app/-help(1)
+Print this message or the help of the given subcommand(s)
+.SH VERSION
+v3.0
diff --git a/clap_mangen/tests/snapshots/quoting.bash.roff b/clap_mangen/tests/snapshots/quoting.bash.roff
new file mode 100644
index 00000000..45412613
--- /dev/null
+++ b/clap_mangen/tests/snapshots/quoting.bash.roff
@@ -0,0 +1,57 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app 3.0" 
+.SH NAME
+my/-app
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-/-single/-quotes/fR] [/fB/-/-double/-quotes/fR] [/fB/-/-backticks/fR] [/fB/-/-backslash/fR] [/fB/-/-brackets/fR] [/fB/-/-expansions/fR] [/fIsubcommands/fR]
+.SH DESCRIPTION
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-V/fR, /fB/-/-version/fR
+Print version information
+.TP
+/fB/-/-single/-quotes/fR
+Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
+.TP
+/fB/-/-double/-quotes/fR
+Can be "always", "auto", or "never"
+.TP
+/fB/-/-backticks/fR
+For more information see `echo test`
+.TP
+/fB/-/-backslash/fR
+Avoid /*(Aq//n/*(Aq
+.TP
+/fB/-/-brackets/fR
+List packages [filter]
+.TP
+/fB/-/-expansions/fR
+Execute the shell command with $SHELL
+.SH SUBCOMMANDS
+.TP
+my/-app/-cmd/-single/-quotes(1)
+Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
+.TP
+my/-app/-cmd/-double/-quotes(1)
+Can be "always", "auto", or "never"
+.TP
+my/-app/-cmd/-backticks(1)
+For more information see `echo test`
+.TP
+my/-app/-cmd/-backslash(1)
+Avoid /*(Aq//n/*(Aq
+.TP
+my/-app/-cmd/-brackets(1)
+List packages [filter]
+.TP
+my/-app/-cmd/-expansions(1)
+Execute the shell command with $SHELL
+.TP
+my/-app/-help(1)
+Print this message or the help of the given subcommand(s)
+.SH VERSION
+v3.0
diff --git a/clap_mangen/tests/snapshots/special_commands.bash.roff b/clap_mangen/tests/snapshots/special_commands.bash.roff
new file mode 100644
index 00000000..f07e2060
--- /dev/null
+++ b/clap_mangen/tests/snapshots/special_commands.bash.roff
@@ -0,0 +1,37 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app 3.0" 
+.SH NAME
+my/-app /- Tests completions
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
+.SH DESCRIPTION
+Tests completions
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-V/fR, /fB/-/-version/fR
+Print version information
+.TP
+/fB/-c/fR, /fB/-/-config/fR
+some config file
+.TP
+some input file
+.TP
+
+.SH SUBCOMMANDS
+.TP
+my/-app/-test(1)
+tests things
+.TP
+my/-app/-some_cmd(1)
+tests other things
+.TP
+my/-app/-some/-cmd/-with/-hyphens(1)
+.TP
+my/-app/-help(1)
+Print this message or the help of the given subcommand(s)
+.SH VERSION
+v3.0
diff --git a/clap_mangen/tests/snapshots/sub_subcommands.bash.roff b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff
new file mode 100644
index 00000000..5d821060
--- /dev/null
+++ b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff
@@ -0,0 +1,35 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app 3.0" 
+.SH NAME
+my/-app /- Tests completions
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
+.SH DESCRIPTION
+Tests completions
+.SH OPTIONS
+.TP
+/fB/-h/fR, /fB/-/-help/fR
+Print help information
+.TP
+/fB/-V/fR, /fB/-/-version/fR
+Print version information
+.TP
+/fB/-c/fR, /fB/-/-config/fR
+some config file
+.TP
+some input file
+.TP
+
+.SH SUBCOMMANDS
+.TP
+my/-app/-test(1)
+tests things
+.TP
+my/-app/-some_cmd(1)
+top level subcommand
+.TP
+my/-app/-help(1)
+Print this message or the help of the given subcommand(s)
+.SH VERSION
+v3.0
diff --git a/clap_mangen/tests/snapshots/value_hint.bash.roff b/clap_mangen/tests/snapshots/value_hint.bash.roff
new file mode 100644
index 00000000..d44e1757
--- /dev/null
+++ b/clap_mangen/tests/snapshots/value_hint.bash.roff
@@ -0,0 +1,53 @@
+.ie /n(.g .ds Aq /(aq
+.el .ds Aq '
+.TH my-app 1  "my-app " 
+.SH NAME
+my/-app
+.SH SYNOPSIS
+/fBmy/-app/fR [/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-unknown/fR] [/fB/-/-other/fR] [/fB/-p/fR|/fB/-/-path/fR] [/fB/-f/fR|/fB/-/-file/fR] [/fB/-d/fR|/fB/-/-dir/fR] [/fB/-e/fR|/fB/-/-exe/fR] [/fB/-/-cmd/-name/fR] [/fB/-c/fR|/fB/-/-cmd/fR] [/fB/-u/fR|/fB/-/-user/fR] [/fB/-h/fR|/fB/-/-host/fR] [/fB/-/-url/fR] [/fB/-/-email/fR] [/fIcommand_with_args/fR] 
+.SH DESCRIPTION
+.SH OPTIONS
+.TP
+/fB/-/-help/fR
+Print help information
+.TP
+/fB/-/-choice/fR
+
+.TP
+/fB/-/-unknown/fR
+
+.TP
+/fB/-/-other/fR
+
+.TP
+/fB/-p/fR, /fB/-/-path/fR
+
+.TP
+/fB/-f/fR, /fB/-/-file/fR
+
+.TP
+/fB/-d/fR, /fB/-/-dir/fR
+
+.TP
+/fB/-e/fR, /fB/-/-exe/fR
+
+.TP
+/fB/-/-cmd/-name/fR
+
+.TP
+/fB/-c/fR, /fB/-/-cmd/fR
+
+.TP
+/fB/-u/fR, /fB/-/-user/fR
+
+.TP
+/fB/-h/fR, /fB/-/-host/fR
+
+.TP
+/fB/-/-url/fR
+
+.TP
+/fB/-/-email/fR
+
+.TP
+