Repository: clap-rs/clap
Pull request #5717 (2024-09-04 14:50:08)

test(complete): Verify more shell integration cases
<!--
Thanks for helping out!

Please link the appropriate issue from your PR.

If you don't have an issue, we'd recommend starting with one first so the PR can focus on the
implementation (unless its an obvious bug or documentation fix that will have
little conversation).
-->



Patch:
diff --git a/clap_complete/examples/exhaustive.rs b/clap_complete/examples/exhaustive.rs
index cbe604ac..7079ed14 100644
--- a/clap_complete/examples/exhaustive.rs
+++ b/clap_complete/examples/exhaustive.rs
@@ -86,6 +86,7 @@ fn cli() -> clap::Command {
                         .long("choice")
                         .action(clap::ArgAction::Set)
                         .value_parser(clap::builder::PossibleValuesParser::new([
+                            PossibleValue::new("another shell").help("something with a space"),
                             PossibleValue::new("bash").help("bash (shell)"),
                             PossibleValue::new("fish").help("fish shell"),
                             PossibleValue::new("zsh").help("zsh shell"),


Test patch:
diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
index b8ce1da5..be558dec 100644
--- a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
+++ b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
@@ -728,7 +728,7 @@ _exhaustive() {
             fi
             case "${prev}" in
                 --choice)
-                    COMPREPLY=($(compgen -W "bash fish zsh" -- "${cur}"))
+                    COMPREPLY=($(compgen -W "another shell bash fish zsh" -- "${cur}"))
                     return 0
                     ;;
                 *)
diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish b/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish
index dd17413c..82c56229 100644
--- a/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish
+++ b/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish
@@ -43,7 +43,7 @@ complete -c exhaustive -n "__fish_exhaustive_using_subcommand action" -l count -
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand action" -l global -d 'everywhere'
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand action" -s h -l help -d 'Print help'
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand action" -s V -l version -d 'Print version'
-complete -c exhaustive -n "__fish_exhaustive_using_subcommand quote; and not __fish_seen_subcommand_from cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" -l choice -r -f -a "{bash\t'bash (shell)',fish\t'fish shell',zsh\t'zsh shell'}"
+complete -c exhaustive -n "__fish_exhaustive_using_subcommand quote; and not __fish_seen_subcommand_from cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" -l choice -r -f -a "{another shell\t'something with a space',bash\t'bash (shell)',fish\t'fish shell',zsh\t'zsh shell'}"
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand quote; and not __fish_seen_subcommand_from cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" -l single-quotes -d 'Can be \'always\', \'auto\', or \'never\''
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand quote; and not __fish_seen_subcommand_from cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" -l double-quotes -d 'Can be "always", "auto", or "never"'
 complete -c exhaustive -n "__fish_exhaustive_using_subcommand quote; and not __fish_seen_subcommand_from cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" -l backticks -d 'For more information see `echo test`'
diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive b/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive
index 4ceaca2d..52819144 100644
--- a/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive
+++ b/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive
@@ -45,7 +45,8 @@ _arguments "${_arguments_options[@]}" : \
 ;;
 (quote)
 _arguments "${_arguments_options[@]}" : \
-'--choice=[]: :((bash\:"bash (shell)"
+'--choice=[]: :((another\ shell\:"something with a space"
+bash\:"bash (shell)"
 fish\:"fish shell"
 zsh\:"zsh shell"))' \
 '--single-quotes[Can be '\''always'\'', '\''auto'\'', or '\''never'\'']' \
diff --git a/clap_complete/tests/testsuite/bash.rs b/clap_complete/tests/testsuite/bash.rs
index 2baec1a0..25461d6f 100644
--- a/clap_complete/tests/testsuite/bash.rs
+++ b/clap_complete/tests/testsuite/bash.rs
@@ -2,6 +2,11 @@ use snapbox::assert_data_eq;
 
 use crate::common;
 
+#[cfg(unix)]
+const CMD: &str = "bash";
+#[cfg(unix)]
+type RuntimeBuilder = completest_pty::BashRuntimeBuilder;
+
 #[test]
 fn basic() {
     let name = "my-app";
@@ -138,19 +143,18 @@ fn subcommand_last() {
 #[test]
 #[cfg(unix)]
 fn register_completion() {
-    common::register_example::<completest_pty::BashRuntimeBuilder>("static", "exhaustive");
+    common::register_example::<RuntimeBuilder>("static", "exhaustive");
 }
 
 #[test]
 #[cfg(unix)]
 fn complete() {
-    if !common::has_command("bash") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::BashRuntimeBuilder>("static", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("static", "exhaustive");
 
     let input = "exhaustive \t\t";
     let expected = snapbox::str![[r#"
@@ -235,19 +239,18 @@ fn complete() {
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn register_dynamic_env() {
-    common::register_example::<completest_pty::BashRuntimeBuilder>("dynamic-env", "exhaustive");
+    common::register_example::<RuntimeBuilder>("dynamic-env", "exhaustive");
 }
 
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_toplevel() {
-    if !common::has_command("bash") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::BashRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive \t\t";
     let expected = snapbox::str![[r#"
@@ -262,13 +265,12 @@ fn complete_dynamic_env_toplevel() {
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_quoted_help() {
-    if !common::has_command("bash") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::BashRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive quote \t\t";
     let expected = snapbox::str![[r#"
@@ -281,3 +283,49 @@ fn complete_dynamic_env_quoted_help() {
     let actual = runtime.complete(input, &term).unwrap();
     assert_data_eq!(actual, expected);
 }
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_option_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive action --choice=\t\t";
+    let expected = snapbox::str!["% "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive action --choice=f\t";
+    let expected = snapbox::str!["exhaustive action --choice=f    % exhaustive action --choice=f"];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_quoted_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive quote --choice \t\t";
+    let expected = snapbox::str![[r#"
+% 
+another shell  bash           fish           zsh            
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive quote --choice an\t";
+    let expected =
+        snapbox::str!["exhaustive quote --choice an    % exhaustive quote --choice another shell "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
diff --git a/clap_complete/tests/testsuite/elvish.rs b/clap_complete/tests/testsuite/elvish.rs
index 564a3963..2dbf9437 100644
--- a/clap_complete/tests/testsuite/elvish.rs
+++ b/clap_complete/tests/testsuite/elvish.rs
@@ -1,6 +1,11 @@
 use crate::common;
 use snapbox::assert_data_eq;
 
+#[cfg(unix)]
+const CMD: &str = "elvish";
+#[cfg(unix)]
+type RuntimeBuilder = completest_pty::ElvishRuntimeBuilder;
+
 #[test]
 fn basic() {
     let name = "my-app";
@@ -137,19 +142,18 @@ fn subcommand_last() {
 #[test]
 #[cfg(unix)]
 fn register_completion() {
-    common::register_example::<completest_pty::ElvishRuntimeBuilder>("static", "exhaustive");
+    common::register_example::<RuntimeBuilder>("static", "exhaustive");
 }
 
 #[test]
 #[cfg(unix)]
 fn complete_static_toplevel() {
-    if !common::has_command("elvish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ElvishRuntimeBuilder>("static", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("static", "exhaustive");
 
     let input = "exhaustive \t";
     let expected = snapbox::str![[r#"
@@ -177,19 +181,18 @@ value          value
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn register_dynamic_env() {
-    common::register_example::<completest_pty::ElvishRuntimeBuilder>("dynamic-env", "exhaustive");
+    common::register_example::<RuntimeBuilder>("dynamic-env", "exhaustive");
 }
 
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_toplevel() {
-    if !common::has_command("elvish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ElvishRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive \t";
     let expected = snapbox::str![[r#"
@@ -205,13 +208,12 @@ fn complete_dynamic_env_toplevel() {
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_quoted_help() {
-    if !common::has_command("elvish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ElvishRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive quote \t";
     let expected = snapbox::str![[r#"
@@ -225,3 +227,61 @@ fn complete_dynamic_env_quoted_help() {
     let actual = runtime.complete(input, &term).unwrap();
     assert_data_eq!(actual, expected);
 }
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_option_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive action --choice=\t";
+    let expected = snapbox::str![[r#"
+% exhaustive action '--choice=first'
+ COMPLETING argument  
+--choice=first  --choice=second
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive action --choice=f\t";
+    let expected = snapbox::str![[r#"
+% exhaustive action '--choice=first'
+ COMPLETING argument  
+--choice=first
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_quoted_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive quote --choice \t";
+    let expected = snapbox::str![[r#"
+% exhaustive quote --choice 'another shell'
+ COMPLETING argument  
+another shell  bash  fish  zsh
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive quote --choice an\t";
+    let expected = snapbox::str![[r#"
+% exhaustive quote --choice 'another shell'
+ COMPLETING argument  
+another shell
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
diff --git a/clap_complete/tests/testsuite/fish.rs b/clap_complete/tests/testsuite/fish.rs
index 4ea55e10..f2ddf4e5 100644
--- a/clap_complete/tests/testsuite/fish.rs
+++ b/clap_complete/tests/testsuite/fish.rs
@@ -1,6 +1,11 @@
 use crate::common;
 use snapbox::assert_data_eq;
 
+#[cfg(unix)]
+const CMD: &str = "fish";
+#[cfg(unix)]
+type RuntimeBuilder = completest_pty::FishRuntimeBuilder;
+
 #[test]
 fn basic() {
     let name = "my-app";
@@ -137,19 +142,18 @@ fn subcommand_last() {
 #[test]
 #[cfg(unix)]
 fn register_completion() {
-    common::register_example::<completest_pty::FishRuntimeBuilder>("static", "exhaustive");
+    common::register_example::<RuntimeBuilder>("static", "exhaustive");
 }
 
 #[test]
 #[cfg(unix)]
 fn complete() {
-    if !common::has_command("fish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::FishRuntimeBuilder>("static", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("static", "exhaustive");
 
     let input = "exhaustive \t";
     let expected = snapbox::str![[r#"
@@ -164,7 +168,7 @@ alias   hint                                                               pacma
     let actual = runtime.complete(input, &term).unwrap();
     let expected = snapbox::str![[r#"
 % exhaustive quote --choice 
-bash  (bash (shell))  fish  (fish shell)  zsh  (zsh shell)
+another shell  (something with a space)  bash  (bash (shell))  fish  (fish shell)  zsh  (zsh shell)
 "#]];
     assert_data_eq!(actual, expected);
 }
@@ -172,19 +176,18 @@ bash  (bash (shell))  fish  (fish shell)  zsh  (zsh shell)
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn register_dynamic_env() {
-    common::register_example::<completest_pty::FishRuntimeBuilder>("dynamic-env", "exhaustive");
+    common::register_example::<RuntimeBuilder>("dynamic-env", "exhaustive");
 }
 
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_toplevel() {
-    if !common::has_command("fish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::FishRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive \t\t";
     let expected = snapbox::str![[r#"
@@ -202,13 +205,12 @@ last                                                               -V  (Print ve
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_quoted_help() {
-    if !common::has_command("fish") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::FishRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive quote \t\t";
     let expected = snapbox::str![[r#"
@@ -237,3 +239,51 @@ help  (Print this message or the help of the given subcommand(s))
     let actual = runtime.complete(input, &term).unwrap();
     assert_data_eq!(actual, expected);
 }
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_option_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive action --choice=\t\t";
+    let expected = snapbox::str![[r#"
+% exhaustive action --choice=first 
+--choice=first  --choice=second
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive action --choice=f\t";
+    let expected = snapbox::str!["% exhaustive action --choice=first "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_quoted_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive quote --choice \t\t";
+    let expected = snapbox::str![[r#"
+% exhaustive quote --choice another/ shell 
+another shell  (something with a space)  bash  (bash (shell))  fish  (fish shell)  zsh  (zsh shell)
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive quote --choice an\t";
+    let expected = snapbox::str!["% exhaustive quote --choice another/ shell "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
diff --git a/clap_complete/tests/testsuite/zsh.rs b/clap_complete/tests/testsuite/zsh.rs
index 43273ffe..2331ff4d 100644
--- a/clap_complete/tests/testsuite/zsh.rs
+++ b/clap_complete/tests/testsuite/zsh.rs
@@ -2,6 +2,11 @@ use snapbox::assert_data_eq;
 
 use crate::common;
 
+#[cfg(unix)]
+const CMD: &str = "zsh";
+#[cfg(unix)]
+type RuntimeBuilder = completest_pty::ZshRuntimeBuilder;
+
 #[test]
 fn basic() {
     let name = "my-app";
@@ -138,19 +143,18 @@ fn subcommand_last() {
 #[test]
 #[cfg(unix)]
 fn register_completion() {
-    common::register_example::<completest_pty::ZshRuntimeBuilder>("static", "exhaustive");
+    common::register_example::<RuntimeBuilder>("static", "exhaustive");
 }
 
 #[test]
 #[cfg(unix)]
 fn complete() {
-    if !common::has_command("zsh") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ZshRuntimeBuilder>("static", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("static", "exhaustive");
 
     let input = "exhaustive \t";
     let expected = snapbox::str![[r#"
@@ -165,19 +169,18 @@ pacman  action  alias  value  quote  hint  last  --
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn register_dynamic_env() {
-    common::register_example::<completest_pty::ZshRuntimeBuilder>("dynamic-env", "exhaustive");
+    common::register_example::<RuntimeBuilder>("dynamic-env", "exhaustive");
 }
 
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_toplevel() {
-    if !common::has_command("zsh") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ZshRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive \t\t";
     let expected = snapbox::str![[r#"
@@ -192,13 +195,12 @@ fn complete_dynamic_env_toplevel() {
 #[test]
 #[cfg(all(unix, feature = "unstable-dynamic"))]
 fn complete_dynamic_env_quoted_help() {
-    if !common::has_command("zsh") {
+    if !common::has_command(CMD) {
         return;
     }
 
     let term = completest::Term::new();
-    let mut runtime =
-        common::load_runtime::<completest_pty::ZshRuntimeBuilder>("dynamic-env", "exhaustive");
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
 
     let input = "exhaustive quote \t\t";
     let expected = snapbox::str![[r#"
@@ -211,3 +213,51 @@ fn complete_dynamic_env_quoted_help() {
     let actual = runtime.complete(input, &term).unwrap();
     assert_data_eq!(actual, expected);
 }
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_option_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive action --choice=\t\t";
+    let expected = snapbox::str![[r#"
+% exhaustive action --choice=
+--choice=first   --choice=second
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive action --choice=f\t\t";
+    let expected = snapbox::str!["% exhaustive action --choice=first "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}
+
+#[test]
+#[cfg(all(unix, feature = "unstable-dynamic"))]
+fn complete_dynamic_env_quoted_value() {
+    if !common::has_command(CMD) {
+        return;
+    }
+
+    let term = completest::Term::new();
+    let mut runtime = common::load_runtime::<RuntimeBuilder>("dynamic-env", "exhaustive");
+
+    let input = "exhaustive quote --choice \t\t";
+    let expected = snapbox::str![[r#"
+% exhaustive quote --choice
+another/ shell  bash            fish            zsh
+"#]];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+
+    let input = "exhaustive quote --choice an\t\t";
+    let expected = snapbox::str!["% exhaustive quote --choice another/ shell "];
+    let actual = runtime.complete(input, &term).unwrap();
+    assert_data_eq!(actual, expected);
+}